niszetの日記

10年目エンジニアが最近勉強したことを忘れないようにメモをする

(R) tuneRとggplot2で作るピアノロール風プロット(図差し替え…)

f:id:niszet:20171129001626p:plain# 既存パッケージだけでいけるじゃないですかー さて、tuneRというパッケージがあります。midiやwave、mp3を入力して色々出来るのですがあまり解説されている記事がないように思えます。

まぁ、今回はtuneRの解説はしないのですが…。需要があれば追々…。

TokyoR 64のLT、そして今回のHijiyamaR Final LTでtuneRでは…なのでrsmfを…とか言っていましたが、色々巡り巡ってtuneR+ggplot2でも出来ることに気づいたので責任とって解説書きます。

プロットしてみる。

さて、適当なmidiファイルは別途用意してみてください。midiデータには著作権があると思いますので、ご注意(例で使っているものはCC0扱いで公開されていたデータセットから)

コード例

コードは下記のようになります。tuneRパッケージ内の関数は明示的にtuneR::をつけていますが、libraryで読み込んでいますのでなくても動作します。

library(tuneR)
library(tidyverse)

mf <- tuneR::readMidi("hogehoge.mid")

mf %>% tuneR::getMidiNotes() %>% ggplot()+geom_segment(aes(
  x=time, y=note, xend=time+length, yend=note,
  color=as.factor(note %% 12), size=1)) + xlim(0, 50000)+
  xlab("time") +  ylab("note") + theme(legend.position="none")+
  scale_colour_brewer(palette = "Paired")

tuneR::readMidi は引数で与えたmidiファイルを読み、結果をdata.frameで返します。

tuneR::getMidiNotesは先の関数で得られたdata.frameのうち、Note(音符)情報だけを抜き出してdata.frameで返します。

曲中でテンポや拍子が変わることがあるのでそれも見ないと本当はいけませんが…割愛。

今回はシンプルに、音情報から音の高さと長さを、何も調整せずにプロットしてみます。

tuneRから得られるdata.frameの中身の説明?

上記コードの変数mf(readMidiで読んだdata.frame)をgetMidiNotes()に与えて得られるdata.frameの中身はこんな感じです。

  time length track channel note notename velocity
1 3840    240     2       0   70      a#'       92
2 4080    240     2       0   74      d''       92
3 4320    480     2       0   77      f''       92
4 4800    240     2       0   70      a#'       92
5 5040    240     2       0   75     d#''       92
6 5280    600     2       0   79      g''       92

midiにふくまれるヘッダやコントロール情報を除いて、note情報だけになりました。

一応、各列の簡単な解説…

timeはなり始めの時間、lengthはその音のなっている時間(長さ)
トラック、チャンネルはそれぞれトラック番号、チャンネル番号
noteは音の高さ、notenameはnoteの名前ですが、ドがC、レがD...です。'でオクターブ違いを表していますね。フラットはあるのだろうか?まだあまり調べ切れていません。 velocityは音量です。

なお、このlengthやtimeはheaderにある情報から何分音符を表しているかがわかるのですが、今回は割愛。

geom_segmentは始点と終点をx,yで指定するgeomです。あまり使うことはないのではないかな…。aesの引数でx,y,xend,yendを指定していますが、xに時間、yに音の高さを示していることになりますね。

colorにはas.factorした、noteを12で割ったあまりにしていますが、この12は1オクターブに含まれる、半音単位の音の数(C, C#, D, D#, E, F, F#, G, G#, A, A#, B)で、オクターブ違いを吸収しています(ドならオクターブうえでも同じ色)

xlab、ylabは軸ラベルですね。themeは凡例を消しています。

scale_colour_brewer(palette = "Paired")は単純に12音分の色があるパレットだったので、ここは任意の12色を指定してみてください。

まぁ、今回はnoteとtimeとlengthしか使わないのですが…。

出力結果

これで出力が下記のようになります。 f:id:niszet:20171128005641p:plain

おー。出来てしまった。

アレンジ

これをちょっと変更すると、、、

mf %>% tuneR::getMidiNotes() %>% ggplot()+geom_segment(aes(
  y=time, x=note, yend=time+length, xend=note,
  color=as.factor(note %% 12), size=1)) + ylim(0, 50000)+
  xlab("time") + ylab("note") + theme(legend.position="none")+
  scale_colour_brewer(palette = "Paired")

こんな感じ。縦が時間、横が音の高さとなってます

f:id:niszet:20171129001626p:plain (図のlabelが間違っていたので差し替えました@0:17)

なんか音ゲーっぽくなりましたね。

ということで、既存のパッケージから、LTで紹介したようなプロットが出来るという紹介でした。

テンポや拍子を考慮するのはちょっと工夫が必要そうですが、それはまた機会があれば。

Enjoy!!

(R) RStudio上でのViewの結果の表示のさせ方、変わりました? (+追記修正)(メモ)

v1.1からの機能ということです。

なんと、今回のHijiyamaRのオープニングで説明があったとのこと…。 資料が公開されたら参照先として追加します(たぶんまだのはず)

実は色々あって開始15分くらい遅刻してしまいました。それらHijiyamaR Finalの感想についてはいずれ。

また、RStudio v1.1の新機能については下記のkazutanさんのブログにまとまっています。 kazutan.github.io

簡単で実用的?な例。

View関数はRStudio上で(に限らないですが)データを表示する際によく使う関数ですが、RStudio上での表示のさせ方が便利だなと思ったので(どうでも良いですが、utilsの中に入ってるんですね、この関数)

たとえば、このようなコードを実行する

View(ggplot())

するとこんな表示に!

f:id:niszet:20171127195550p:plain

…以前からなりましたっけ?まぁ、今あって、便利に使えることが大事…。

Typeで型(classかな)、Valueにその値が表示されるのもポイント高いですね…。

これのさらに良い点は、図の右の方に白いアイコンが出ていますが、これをクリックするとその行のデータを選択するためのコードがコンソール上に書かれるという点です。 上図の場合、

ggplot()[["theme"]]

がコンソール上に書かれます。

また、対象の行がdata.frameの場合、そのデータをView()するためのアイコンが、コンソールにコマンドを表示するアイコンの左に出てきます。data.frameをlist(あとはS3 classとか)の要素に持っている場合などに便利な気がします。

具体的な使いどころ

上記の例もggplot2パッケージの出力を見ていましたが、kazutanさんの下記の記事、

ggplotのオブジェクトから眺めてみる

を意識しています。strでも追えるのですが、階層構造が複雑になってくるとやっぱりしんどいものがあるので、View()で簡単に表示・選択できることは特に初心者にはありがたい機能だと思います。

なお、上記

RStudio.Version()
# $citation
# 
# To cite RStudio in publications use:
# 
#   RStudio Team (2016). RStudio: Integrated Development for R. RStudio, Inc., Boston,
#   MA URL http://www.rstudio.com/.
# 
# A BibTeX entry for LaTeX users is
# 
#   @Manual{,
#     title = {RStudio: Integrated Development Environment for R},
#     author = {{RStudio Team}},
#     organization = {RStudio, Inc.},
#     address = {Boston, MA},
#     year = {2016},
#     url = {http://www.rstudio.com/},
#   }
# 
# 
# $mode
# [1] "desktop"
#  
#  $version
#  [1] ‘1.1.383’

の環境のRStudioを使用しています。

Enjoy!!

(R) cliパッケージ (メモ)

アドカレ向け。

tidyverseが1.2になった際に色々と更新されました(今は1.2.1)が、その中にcliパッケージがあります。

脱線。

確認してみます。crayonもここで見れますね。

tidyverse::tidyverse_packages()
#  [1] "broom"       "cli"         "crayon"      "dplyr"       "dbplyr"      "forcats"    
#  [7] "ggplot2"     "haven"       "hms"         "httr"        "jsonlite"    "lubridate"  
#  [13] "magrittr"    "modelr"      "purrr"       "readr"       "readxl\n(>=" "reprex"     
#  [19] "rlang"       "rstudioapi"  "rvest"       "stringr"     "tibble"      "tidyr"      
#  [25] "xml2"        "tidyverse"  

…あれ?なんか出力がおかしい(readxlのとこ)

tidyverse::tidyverse_packages
function (include_self = TRUE) 
{
    raw <- utils::packageDescription("tidyverse")$Imports
    imports <- strsplit(raw, ",")[[1]]
    parsed <- gsub("^\\s+|\\s+$", "", imports)
    names <- vapply(strsplit(parsed, " +"), "[[", 1, FUN.VALUE = character(1))
    if (include_self) {
        names <- c(names, "tidyverse")
    }
    names
}

DescriptionのImportsを見ているようですが、たしかにreadxlが直後に改行されているのでこうなるな…

        modelr (>= 0.1.1), purrr (>= 0.2.4), readr (>= 1.1.1), readxl
        (>= 1.0.0), reprex (>= 0.1.1), rlang (>= 0.1.4), rstudioapi (>=

何か言った方が良いのかしらん…(えいごわからんぐ…)

元に戻って

昨日のcrayonもそうですが、コンソール上でデータを見やすくする流れがあるようですね。u_riboさんが詳しそう。

↑のツイートのprecisパッケージの紹介記事はこちら↓ですね。

uribo.hatenablog.com

たしかに見やすい…

コンソール上でもっとvisualizeされる流れが加速すると、探索的なデータの解析にさらに便利になりそうですね(こなみ)

Enjoy!!

(R) crayonパッケージ (メモ)

Hadleyやr-libのパッケージを見るのは楽しい。

アドカレにとっとけ!って感じですが、必要なら焼き直せばよいのです…(なので、メモレベルしかかかない)

最近、Rの出力に色を付けるのが流行っている気がします。先日のusethisの結果もカラフル(はてなブログの機能では表現できないので、RStudio上で実行して結果を見てください)

で、そんな色付けなどの装飾をするパッケージ、crayonですが、

github.com

のサンプルを実行するだけでも時間を忘れてしまいます。実行例を見るに、cat()で受けてあげれば良いようなので、結構お手軽ですね(受けなければ文字列として得られるし、linuxのterminal上で色を付けているのと同じようなことをしているんだな、ということがわかります。

CRAN版の逆依存パッケージを見ると、tidyverseが含まれていますので、最新のtidyverseを入れている人は既に入っていて使えるはずです。

CRAN - Package crayon

pillarというパッケージもcrayonを使っていて、

github.com

pillar is not designed for end-users but will eventually be incorporated in packages like tibble.

ということで、tibbleなどに入っていくような気配。実行例を見るとNAが強調されてますね。コレいいかも

以上、メモでした。

Enjoy!!

(R) usethisパッケージ (メモ)

バージョンが1.1.0になった

どこかでおススメ記事を見た気がするんですが、見つからず。Hadley自身のツイートで知ったのかもしれない。

CRAN - Package usethis

Automate package and project setup tasks that are otherwise performed manually. This includes setting up unit testing, test coverage, continuous integration, Git, 'GitHub', licenses, 'Rcpp', 'RStudio' projects, and more.

だそうです。パッケージを作る際に必要なものを準備してくれたりして便利(パッケージじゃないプロジェクトではあまり意味がない)

例えば、

# NEWS.mdを作ってくれます
usethis::use_news_md()
#  ✔ Writing 'NEWS.md'
#  ● Modify 'NEWS.md'

# testthat用のdirとファイルを作ってくれます
usethis::use_testthat()
#  ✔ Adding 'testthat' to Suggests field in DESCRIPTION
#  ✔ Creating 'tests/testthat/'
#  ✔ Writing 'tests/testthat.R'

実際に出力される文字は色付きで見やすく、綺麗です。

他にも便利関数が沢山あって、パッケージ作る際にはぜひ使いこなしたいですね(私もさっき触り始めたので、これから使っていく予定です)

Enjoy!!

(R) !! の読み方 (メモ)

たまたま目に入ったので忘れないようにメモ

Hadleyはこう読んでるんですねぇ…。真似してみよ。

(R) Rで 0xFFL と 書いてみる(11/18追記)

言語仕様?

16進数ってのがあります。16で繰り上がるので、10がA、11がB...で15をFで表します。

0xFFは 0xが16進数であることを示し、はじめのFは16x15、あとのFの15とあわせて 16x15 + 15 = 255 でおなじみの?数字になります。

さて、Rでこの0xFFをコンソールに入力すると

0xFF
# [1] 255

こうなります。ちゃんと?10進数にしてくれるのですね。

しかし型を見てみると、

str(0xFF)
#  num 255

なんと?numericです。integerじゃないのか…

末尾にLをつけると整数型になる

Rで整数型にする場合は末尾にLをつけると出来ますよね。

1
# [1] 1
str(1)
#  num 1

# numericが返ってくる。

1L
# [1] 1
str(1L)
#  int 1

# integerが返ってくる

これは先の16進数でも同じで、

str(0xFF)
#  num 255
0xFFL
# [1] 255
str(0xFFL)
#  int 255

となります。だから何だって話ですが。

この、0x**の書き方について、Rの言語仕様的にどこかに書かれているのだと思うのですが未だに見つけられず。

少し古いドキュメントですけども、例えばこれ

https://cran.r-project.org/doc/contrib/manuals-jp/R-lang.jp.v110.pdf

にも書かれていません。

まぁ、動くので良いのですが。。。。

今作成中のrYMF825でこの書き方を使っているので、仕様としてどう決まっているのかなーと思った次第です。

ちなみに、 qiita.com

で知りましたが、as.hexmodeという関数があるようで

str(as.hexmode("FF"))
# Class 'hexmode'  int 255

のようにclassで扱うのですね。

さらに、read_csvで読み込む場合、0xFFは文字列として扱われてしまいます。読んだ後にas.integerすると良いと思います(型を指定するとうまく読めなかった) これはまた次回?書きますか…

このあたり(rawとか)は情報があまりないのですよね…本来の使い方じゃないからか…

Enjoy!!

追記

ホクそうむさんに教えていただきました。R Language Definitionの3.1.1や10.3.1など、にいちおう記載はありますとのことで、

cran.r-project.org

So ‘0x10L’ creates the integer value 16 from the hexadecimal representation. 
Numeric constants can also be hexadecimal, starting with ‘0x’ or ‘0x’ followed by zero or more digits, ‘a-f’ or ‘A-F’. Hexadecimal floating point constants are supported using C99 syntax, e.g. ‘0x1.1p1’.

などがありました。C99のsyntaxを見ればよいようですね。

やはり大元の情報に当たっていくのが良いですね…

改めて

Enjoy!!