R言語によるデータソニフィケーション超入門

この記事について
この記事はR言語 Advent Calendar 2025の5日目の記事になる予定です。
私のアドカレ3日目の記事では、Rでアートをつくるために開発した一連のパッケージについて、実際につくった作品の例とあわせて紹介しました。そちらは、この2025年にかなり力を入れて取り組んだ活動だったため、紹介記事としてもけっこう気合いを入れて書いています。まだ読まれていない方は、ぜひ読んでみてください。
一方のこの記事では、3日目よりもすこし肩の力を抜いて、R言語で簡単なデータソニフィケーションに挑戦してみたというネタっぽい話をしようと思います。もちろん、データソニフィケーションそれ自体はまったくネタではないというか、技術的に非常にチャレンジングな領域ではあるのですが、ここで紹介するのは、思いつきでつくった自作パッケージを使った、ごく簡単な可聴化の話になります。
R言語でggplotから音をつくるパッケージつくってる。音量注意!
— あきる (@paithiov909) November 10, 2025
わかったこと「たしかに音を鳴らせるんだけど、鳴らしたところでぜんぜん意味がわからない」 pic.twitter.com/811SfzmsBt
いわば「なんちゃって・データソニフィケーション」の事例紹介ですが、「R言語を使ってデータを音にする」というのは、試みとしてはめずらしくて、面白いんじゃないかなと思います。
データソニフィケーションについて
データソニフィケーションとは
早速何をどうやるのか説明したいところですが、まずはじめに、データソニフィケーションという用語について確認しましょう。
ソニフィケーション(sonification)というのは、非言語音を使って、データについて何かを伝えるような伝達手法のことを指します。ビジュアライゼーションが可視化と呼ばれるのに対して、ソニフィケーションは可聴化と呼ばれたりもします。いわば、データを「聴ける化」するような手法全般のことを指す、広い意味のことばです。
データソニフィケーションは、可視化ほど一般的ではないものの、すごく目新しい用語というわけではありません。ソニフィケーションについてインターネットで調べると出てくるThe Sonification Handbookが公開されたのが2011年のことらしいですし、それ以後に書かれたデータソニフィケーションについて触れているブログ記事などもちらほら存在します。もうすこしフォーマルな場における日本語の紹介としては、たとえば、2018年の音響学会誌の小特集として掲載された次の文章などが見つかります。
また、もっと最近に書かれたアクセスしやすい資料としては、Aura Walmerさんという方が公開したData Sonification ToolkitというWebサイトがあります。
このあたりの資料を参考に、もうすこし説明すると、データを「聴ける化」するような手法は、大まかなやり方によって次のようなタイプに分けられます。
- 聴覚化(audification)
- 聴覚アイコン(auditory icon)
- イアコン(earcon)
- パラメータマッピングによる可聴化(parameter mapping sonification)
- モデルベースの可聴化(model-based sonification)
それぞれのタイプがどのような可聴化手法なのかといった説明については上で紹介した資料などを読んでもらうとして、このなかでもっとも一般的におこなわれているのは、パラメータマッピングによる可聴化です。これは、データ可視化になじみがある人向けに説明するならば、データの特徴量を「音」の特徴量にマッピングしてやることによって、「音」としてグラフを描くような手法にあたります。
パラメータマッピングの難しい点
「音」としてグラフを描くという説明をするかぎりでは、一見すると、それほど難しくない作業のように思えますよね?
実際、データの特徴量を、音高(pitch)、音量(loundness)、音色(timbre)などに対応づけることができれば、データから何らかの「音」を鳴らすことはできます。Rでggplot2の使い方がわかれば誰でも簡単にグラフを描けるのと同じで、マッピングのやり方さえわかってしまえば、データを音に変換することだって、誰にでも簡単にできそうです。
しかし、ややめんどうなポイントして、「音」というのはグラフと違って時間的な要素があるものなので、データからのマッピング先には「音」としての長さやリズム、テンポなどが含まれます。また、もっと重大なポイントとして、意味のある可聴化をおこなうことは、意味のある可視化をおこなうこと以上に難しい場合が多いです。
とくに後者の注意点がどのようにして問題化するのかを考えてみましょう。ここでは、シンプルなパラメータマッピングをおこなうことを想定し、可聴化したいデータを2つの特徴量にもとづいて時間軸(X)と音高の軸(Y)からなる空間に配置するものとします。
これは、イメージとしては、DAWにおけるピアノロール(piano roll)のような図をつくろうとするのと同じことで、ggplot2でいえばgeom_step()を使ってデータ点のあいだに線分を引いていくのに近いです。
library(ggplot2)
ggplot(iris) +
geom_step(aes(x = Sepal.Length, y = Petal.Length, linewidth = Petal.Length, alpha = Petal.Length, group = Species, color = Species), lineend = "round")

つまりこういうイメージなんですけど、irisはSpeciesごとの特徴によってまとまりを分離できることがわかっているから、Speciesの違いを可視化するのは簡単なはずなんです。一方で、じゃあ、次のような音源を聞いたとして、上のグラフから読み取れるのと同じような情報を聞き取ることができるのかというと、それはなかなか大変だろうと思うんですよね。
私たちは、データをグラフを使って可視化することや、そうしたグラフから情報を読み取ることに関しては、学校での教育などを通じて訓練を受けているので、わりとできます。しかし、データを可聴化することや、そうして可聴化された音源から情報を聞き取るということに関しては訓練を受けていないので、どういう点に注意してパラメータマッピングすれば効果的で、どういう点に注意して聞けばどんなことを聞き取れるのかといった可聴化のコツは、ふつうはまったく知らないはずです。
もちろん、きちんとした意図をもって適切にデザインされた可聴化からであれば、誰でもある程度同じような情報を引き出すことができるのでしょうし、ソニフィケーションを専門的に扱っている研究者などであれば、そういうコツを知っているのだろうと思います。
しかし、たとえば、可視化の範囲内であっても、UpSet plotとか一目均衡表のような、自分があまり見たことがないような表現については、それがどんなグラフなのか知らないかぎり、適切に描くのも読み取るのも難しいものです。それと同様に、パラメータマッピングで可聴化する場合でもマッピングのやり方さえわかればOKという話ではなく、どういう変数をどうマッピングすれば、自分が伝えたいメッセージが適切に伝達できそうか、あらかじめきちんと把握しておく必要があります。そして、そのためにはおそらく、相応の練習が必要不可欠です。
既存のパラメータマッピングの方法
そんな感じで、パラメータマッピングは、「音」としてグラフを描くというシンプルなアイデアのわりに癖のある手法なわけですが、そのあたりの扱いづらさを解決しようとした既存のプロジェクトがいくつかあります。
TwoToneは、CSVデータなどを突っ込むと、そのデータをもとにメロディがつくれるというWebアプリでした。Webアプリはまだ残っていますが、開発はすでに止まっているようです。また、Julianna Langstonさんのchart2musicは、Chart.jsとかPlotlyなどのグラフライブラリからデータを引っこ抜くことで、グラフを音として「聞ける化」するJS/TSのライブラリになります。
また、R言語にも、データソニフィケーションを目的としたパッケージがいくつかあるようです。
- sonify: Data Sonification - Turning Data into Sound
- statisfactions/playitbyr
- benRenard/sequenceR
- neuwirthe/midisonifyR
midisonifyRは、この開発者がつくったいくつかのパッケージに依存しているらしい野良パッケージです。これ以外の3つはCRANにある(かつてあった)パッケージで、いずれもデータをもとにして音声信号を合成するような仕組みのもののようです。3つのなかではsequenceRがもっとも新しく、機能的にも充実していますが、たぶん本格的なソニフィケーションをおこなう用途のパッケージなので、実際に使おうとするとちょっと敷居が高そうではあります。
pipopaplotによるパラメータマッピングの例
概要
何はなくとも練習が必要そうなことは確かなので、とにかく手軽にパラメータマッピングを試せるRパッケージがあれば便利そうです。その点、midisonifyRのようにMIDIを書き出すことをゴールにするという方法は扱いやすそうだったので、それを真似しながら、簡単なRパッケージをつくってみました。
たとえば、先ほどの音源は、このpipopaplotを使って次のようにしてつくったものです(MIDIはWebページ上では再生しづらいため、実際にはmp3に変換しています)。
gp <- iris |>
ggplot(aes(x = Sepal.Length, y = Petal.Length, linewidth = Petal.Length, alpha = Petal.Length)) +
geom_step(lineend = "round") +
facet_wrap(~ Species)
midi_dat <- gp |>
pipopaplot::as_notes(velocity = "linewidth") |>
pipopaplot::rollup(x) |>
pipopaplot::sonify(phrase_len = 16, offset = .125)
# `opt`から、`tpq`と、`programs`(各`channel`に対応するMIDIの音色番号)を指定できます
pipopaplot::write_midi(midi_dat, "iris1.mid", opt = list(programs = c(5L, 6L, 7L)))
このRパッケージは、特定の名前の列を含むデータフレームから、データ点をMIDIノートにパラメータマッピングするための関数と、マッピングしたデータをMIDIファイルへ書き出すための関数を提供しています。
as_notes
もうすこし遊びながら、詳しく見てみましょう。まず、pipopaplot::as_notes()は、実際にパラメータマッピングする関数に突っ込むための「特定の名前の列を含むデータフレーム」を用意するヘルパー関数です。ggplotオブジェクトを受け取ると、次のようなデータフレームを返します。
gp <- iris |>
ggplot(aes(x = Sepal.Length, y = Petal.Length, group = Species)) +
geom_point()
notes <- pipopaplot::as_notes(gp)
str(notes)
#> tibble [150 × 6] (S3: tbl_df/tbl/data.frame)
#> $ x : num [1:150] 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
#> $ y : num [1:150] 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
#> $ channel : Factor w/ 1 level "1": 1 1 1 1 1 1 1 1 1 1 ...
#> $ group : num [1:150] 1 1 1 1 1 1 1 1 1 1 ...
#> $ velocity: num [1:150] 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 1.5 ...
#> $ duration: num [1:150] 1 1 1 1 1 1 1 1 1 1 ...
返される列名はこれで固定です。ggplotオブジェクトを受け取る場合、channelはPANEL(facet_wrap(~ var)したときのvar)から、velocityはsizeから、durationはalphaから取られます。ggplotのレイヤーから得られるデータにこれらの情報が含まれない場合には、先ほどの例のようにpipopaplot::as_notes(velocity = "linewidth")とかして、取ってくる列名を指定すれば動かせます。あるいは、これの戻り値と列名・各列の型があっているのであれば、自分で同じ構造のデータフレームをつくっておくのでもOKです。
sonify
この形のデータフレームはpipopaplot::sonify()に渡すことで、MIDIのノートイベント列を表すデータに変換できます。
midi_dat <- notes |>
pipopaplot::sonify()
str(midi_dat)
#> tibble [35 × 6] (S3: tbl_df/tbl/data.frame)
#> $ channel : Factor w/ 1 level "1": 1 1 1 1 1 1 1 1 1 1 ...
#> $ group : Factor w/ 3 levels "1","2","3": 1 1 1 1 1 1 1 1 1 1 ...
#> $ tick_on : int [1:35] 1600 1344 1088 960 1472 1984 704 1216 576 2496 ...
#> $ tick_off: int [1:35] 1648 1392 1136 1008 1520 2032 752 1264 624 2544 ...
#> $ pitch : int [1:35] 32 32 31 33 32 36 32 35 28 30 ...
#> $ velocity: int [1:35] 80 80 80 80 80 80 80 80 80 80 ...
内部的にはscales::rescale()を使って、それぞれの変数を素直にマッピングしているだけです。channelについては音色の違いに対応します。また、groupは、番号ごとにグルーピングしながら、番号が若い方から順番に時間軸上に配置するための変数です。一つ一つのグループは、デフォルトではTPQ(ticks per quarter note)が480だとして四分音符4拍分の長さになるようにしてあって、この単位をpipopaplotではフレーズと呼びます。
ここで試しているirisではSpeciesは3水準あるため、このmidi_datをpipopaplot::write_midi()に渡してMIDIファイルに書き出すと、同じ音色でそれぞれのグループに対応するフレーズが順番に再生されます(ここではsetosa, versicolor, virginicaの順)。
pipopaplot::write_midi(midi_dat, "iris2.mid")
rollup
pipopaplotでできることは基本的にこれだけなのですが、くわえて、as_notes()とsonify()のあいだに任意の処理を挟むことも可能です。
というのも、irisだと含まれている観測の数が少ないのであまり関係ないものの、もっとたくさんの観測からなるデータをsonify()する場合、それぞれの観測が一つずつMIDIノートになってしまうと、フレーズ中でたくさんの音が鳴りすぎて、きっとわけがわからなくなることでしょう。pipopaplot::sonify()は、同一channel内でまったく同じタイミングに鳴り始めることになるノートについてはdplyr::distinct()で自動的に間引いてしまいますが、実際にMIDIノートにマッピングされる点をコントロールしたい場合には、あらかじめ自分で観測を集約しておくのが有効です。
pipopaplot::rollup()は、そうした集約をおこなうためのヘルパー関数です。中身は次のようなものになっています。
pipopaplot::rollup
#> function (d, by, .fun = base::mean)
#> {
#> grouping_vars <- rlang::syms(c("channel", "group"))
#> summarise(group_by(d, !!!grouping_vars, {
#> {
#> by
#> }
#> }), across(where(is.numeric), .fun), .groups = "drop")
#> }
#> <bytecode: 0x5c7e7fc7b270>
#> <environment: namespace:pipopaplot>
ここについては、as_notes()して返されるデータフレームと同じ列名・型が保たれているかぎり、実際には何をしてもかまわないので、無理にこのrollup()を使わなくても問題ありません。ノートになる点を減らす方向ばかりではなく、規則的に増やすような処理をおこなっても全然大丈夫です。むしろ、ここで自由にreframeすることができる余地があることによって、たとえば和音が鳴るようにしたり、メロディをつくったりといったことも(理屈上は)可能になっています。ぜひ、いろいろ試して遊んでみてください。
まとめ
といったわけで、Rでパラメータマッピングによるデータソニフィケーションをおこなえる簡単なパッケージをつくったことを紹介しました。
実際のところ、このpipopaplotパッケージを使って、本格的なソニフィケーションをおこなえるのかというと、それはなかなか厳しいような感じがします。そもそも「本格的なソニフィケーション」というのがどういった手段でおこなわれるものなのかもよくわからないですが、少なくともpipopaplotの目的は、簡単にパラメータマッピングがおこなえる手段を提供することを通じて、パラメータマッピングに慣れ親しむことができるようなきっかけをつくることだと思っています。
実際、そもそもやり方がさっぱりわからないものは練習のしようもないですから、ごく簡単な仕組みのものであっても、とりあえず手軽に試せるということはとても重要です。その意味で、pipopaplotは簡単な可聴化を試しながら遊んでみるための「おもちゃ」みたいな位置づけのパッケージで、pipopaplotという名前にはそういう遊び心が伝わればいいなという気持ちが込められています。
「データソニフィケーションに興味が出てきたけど、何から試せばいいかわからない」となったとき、pipopaplotのことを思い出してもらって、試しに遊んでみてもらえたら嬉しいです。
