はじめに
この記事では,よくある刺激のリストをJSON形式で保持するということをRを使ってやってみます。ただのデータフレームをJSON形式に変換するのはそれほど難しいことではありません。むしろ,Rを使わなくてもウェブ上で変換してくれるサービスがあります。
https://tableconvert.com/
こういうのを使うと,下記のようなテーブル形式のデータをcsvで持っていたとしたら,それをJSON形式に変換するのは一瞬です。
| id | name | age | gender |
|---|---|---|---|
| 1 | Roberta | 39 | M |
| 2 | Oliver | 25 | M |
| 3 | Shayna | 18 | F |
| 4 | Fechin | 18 | M |
#JSON形式
[
{"id":1,"name":"Roberta","age":39,"gender":"M"},
{"id":2,"name":"Oliver","age":25,"gender":"M"},
{"id":3,"name":"Shayna","age":18,"gender":"F"},
{"id":4,"name":"Fechin","age":18,"gender":"M"}
]
問題の所在
じゃあ別にそのウェブサービスでいいじゃんということになるんですが,問題は少しこれより複雑です。というのも,私は今 jsPsychを使って実験ができるようにと勉強しています。jsPsychではJSON形式で刺激を読み込むのですが,その際に,データに階層性が必要になってくるようです。別に,反応の取得だけを目的とするなら必要ないのですが,のちのデータ分析を楽にすることを考えると,これは実験の前の段階でやっておきたいです1。jsPsychのページでは以下のように例が示されています。
var test_stimuli = [
{ stimulus: "img/blue.png", data: {test_part: 'test', correct_response: 'f'}},
{ stimulus: "img/orange.png", data: {test_part: 'test', correct_response: 'j'}}
];
この例では,刺激として画像を提示するので,“stimulus”として画像ファイルが指定されています。そして,その後ろにdataという変数があって,要するに,実際に表示される刺激と,その刺激に付随する情報(正誤,刺激の種類等)が分かれていて,付随する情報は一つ階層が下のレベルに入っているということです。リストの中にリストがあるということですね。こうなると,ただのデータフレームからの変換というわけにはいかないので,先ほど紹介したようなウェブブラウザで変換というわけにもいきません。というわけで,Rを使って,できるだけ簡単にデータフレームから階層性のあるリストをゲットしましょう。というのが今回の目標です。実は,リスト->データフレームという話は,rlistパッケージ周りでやってる方が結構いらっしゃるようです(Googleで「rlist データフレーム 」と検索してみてください)。ところが,今回のようにデータフレーム->リストはあまり例が見つかりませんでした。ということでやってみましょう。結論から先にいうと,めちゃくちゃ単純でした。
1. データの準備
まずは,わかりやすい刺激リストの例として自分が最近実験で使った刺激リストを読み込みます。
dat<-read.csv("stimuli.csv")
head(dat)
一応,各列に何が入っているかを簡単にまとめると,以下のようになります。
- itemID: 刺激のID(かぶりがありますが,nonwordは分析から最初に外すのでとりあえずOK。ほんとは連番のがいいですけど)
- type: 刺激の種類
- word: ターゲットとなる英単語
- kana: 対応するカタカナ語
- pic: 提示する画像
- lang: 提示する言語
- prime: プライミング条件
- answer: 正答
- form: フォーム
- freq_J: カタカナ語の頻度
- freq_E: 英単語の頻度
この実験では,まずはじめに画像を提示して,参加者はその画像を見ます。画像を理解したら次に注視点が表示されます。その後に提示された文字列が実在語かどうかを判断する語彙性判断課題です。プライミングの条件がshare, spec, baseと3条件あります。さて,プログラム上では,
- 画像(pic)を提示
- 語(word)を提示
ということで,上で紹介した例と異なって,提示する刺激が2種類あります(ここでは,提示刺激は英単語のみとして進めます。カタカナ語の場合は英単語の部分をカタカナ語の列に置き換えれば良いと考えます)。つまり,
{ pic: "img/2_C_sh.jpg", word: "interview", data: {itemID: '2', kana: 'インタビュー', lang: 'eng', prime: 'share',answer: 'TRUE',form: 'A',freq_J: '29.5098', freq_E: '17.5744'}}
というのを読み込んだデータフレームのすべての行において作ることができれば成功となります。
2. パッケージの準備
とりあえず,これ入れとけばいいかなということでtidyverseパッケージと,最後にJSON形式に変換する際に使うjsonliteパッケージ。
install.packages("tidyverse")
install.packages("jsonlite")
library(tidyverse)
library(jsonlite)
3. データハンドリング
tibbleという比較的新しいデータ形式を使います。tidyrとかdplyrとか使うようになって,数年前からこのtibble形式がよく出てきてたんですが,私もいまいちよくわかってませんでした。というか,データフレームを扱うことがほとんどなので,データフレーム形式しか受け付けない関数にtibbleで出力された結果をうっかり渡してエラー吐くみたいなことが頻発したのでいちいちas.data.frame()でデータフレーム型に強制的に直すみたいなことをしてました。
ところが,今回みたいな階層性のある形については,tibble型が便利なようですね。tibbleでは,リスト型の列を持つことができるので,“data”の列に刺激の情報をまとめたリストを入れていけばいいということになります。そう考えて,次のようにやってみました。
tibble::tibble(
pic=dat$pic,
word=dat$word,
data=list(dat[,c(1,2,4,6,7,8,9,10,11)])
)->dat2
ところが,これで中身を見てみると…
head(dat2)
## # A tibble: 6 x 3
## pic word data
## <fct> <fct> <list>
## 1 2_C_sh.jpg interview <df[,9] [48 × 9]>
## 2 3_C_sp.jpg court <df[,9] [48 × 9]>
## 3 6_C_sh.jpg alien <df[,9] [48 × 9]>
## 4 7_C_sp.jpg appointment <df[,9] [48 × 9]>
## 5 10_C_sh.jpg stamp <df[,9] [48 × 9]>
## 6 14_C_sh.jpg channel <df[,9] [48 × 9]>
head(dat2$data,3)
## [[1]]
## itemID type kana lang prime answer form freq_J
## 1 2 target インタビュー eng share TRUE A 29.5098
## 2 3 target コート eng spec TRUE A 100.7255
## 3 6 target エイリアン eng share TRUE A 17.4314
## 4 7 target アポイントメント eng spec TRUE A 30.5686
## 5 10 target スタンプ eng share TRUE A 5.9216
## 6 14 target チャンネル eng share TRUE A 24.4118
## 7 15 target クロール eng spec TRUE A 12.0392
## 8 18 target センス eng share TRUE A 131.8039
## 9 19 target ベンチ eng spec TRUE A 9.6667
## 10 22 target プロモーション eng share TRUE A 10.9216
## 11 23 target ツナ eng spec TRUE A 8.0000
## 12 1 target アイロン eng base TRUE A 17.9412
## 13 4 target グラウンド eng base TRUE A 72.4706
## 14 5 target アドレス eng base TRUE A 52.2745
## 15 8 target プレッシャー eng base TRUE A 53.1176
## 16 9 target プロポーズ eng base TRUE A 13.0000
## 17 12 target ボリューム eng base TRUE A 6.9412
## 18 13 target ベース eng base TRUE A 35.3725
## 19 16 target エクスプレス eng base TRUE A 17.9216
## 20 17 target ストーブ eng base TRUE A 7.5882
## 21 20 target リコール eng base TRUE A 19.6667
## 22 21 target レター eng base TRUE A 82.6078
## 23 24 target ガッツ eng base TRUE A 23.7451
## 24 25 target バイク eng base TRUE A 25.8824
## 25 17 nonword ドートレギング eng <NA> FALSE <NA> NA
## 26 18 nonword フィスティレド eng <NA> FALSE <NA> NA
## 27 19 nonword ストネヘンデ eng <NA> FALSE <NA> NA
## 28 20 nonword ポリディフィエス eng <NA> FALSE <NA> NA
## 29 21 nonword メストレイヤーズ eng <NA> FALSE <NA> NA
## 30 22 nonword ドンスーン eng <NA> FALSE <NA> NA
## 31 23 nonword スプラム eng <NA> FALSE <NA> NA
## 32 24 nonword ティソベディエント eng <NA> FALSE <NA> NA
## 33 25 nonword ムイン eng <NA> FALSE <NA> NA
## 34 26 nonword ドソーム eng <NA> FALSE <NA> NA
## 35 27 nonword ヘイド eng <NA> FALSE <NA> NA
## 36 28 nonword オンテナー eng <NA> FALSE <NA> NA
## 37 29 nonword タンサック eng <NA> FALSE <NA> NA
## 38 30 nonword フロール eng <NA> FALSE <NA> NA
## 39 31 nonword アンチヒスタモーネ eng <NA> FALSE <NA> NA
## 40 32 nonword パラックス eng <NA> FALSE <NA> NA
## 41 33 nonword ハイプノジスト eng <NA> FALSE <NA> NA
## 42 34 nonword クロリエイジ eng <NA> FALSE <NA> NA
## 43 35 nonword コラプソス eng <NA> FALSE <NA> NA
## 44 36 nonword ビキナ eng <NA> FALSE <NA> NA
## 45 37 nonword スティメレーション eng <NA> FALSE <NA> NA
## 46 38 nonword スキマッド eng <NA> FALSE <NA> NA
## 47 39 nonword ディロクトネス eng <NA> FALSE <NA> NA
## 48 40 nonword ケグファグ eng <NA> FALSE <NA> NA
## freq_E
## 1 17.5744
## 2 21.4056
## 3 0.5272
## 4 0.5272
## 5 3.3743
## 6 20.8784
## 7 0.3163
## 8 11.7045
## 9 13.9541
## 10 2.4253
## 11 5.2020
## 12 3.6555
## 13 9.2793
## 14 31.5284
## 15 5.7292
## 16 2.2847
## 17 14.9382
## 18 40.7726
## 19 2.5307
## 20 3.5852
## 21 0.7030
## 22 3.5500
## 23 3.6906
## 24 13.8135
## 25 NA
## 26 NA
## 27 NA
## 28 NA
## 29 NA
## 30 NA
## 31 NA
## 32 NA
## 33 NA
## 34 NA
## 35 NA
## 36 NA
## 37 NA
## 38 NA
## 39 NA
## 40 NA
## 41 NA
## 42 NA
## 43 NA
## 44 NA
## 45 NA
## 46 NA
## 47 NA
## 48 NA
##
## [[2]]
## itemID type kana lang prime answer form freq_J
## 1 2 target インタビュー eng share TRUE A 29.5098
## 2 3 target コート eng spec TRUE A 100.7255
## 3 6 target エイリアン eng share TRUE A 17.4314
## 4 7 target アポイントメント eng spec TRUE A 30.5686
## 5 10 target スタンプ eng share TRUE A 5.9216
## 6 14 target チャンネル eng share TRUE A 24.4118
## 7 15 target クロール eng spec TRUE A 12.0392
## 8 18 target センス eng share TRUE A 131.8039
## 9 19 target ベンチ eng spec TRUE A 9.6667
## 10 22 target プロモーション eng share TRUE A 10.9216
## 11 23 target ツナ eng spec TRUE A 8.0000
## 12 1 target アイロン eng base TRUE A 17.9412
## 13 4 target グラウンド eng base TRUE A 72.4706
## 14 5 target アドレス eng base TRUE A 52.2745
## 15 8 target プレッシャー eng base TRUE A 53.1176
## 16 9 target プロポーズ eng base TRUE A 13.0000
## 17 12 target ボリューム eng base TRUE A 6.9412
## 18 13 target ベース eng base TRUE A 35.3725
## 19 16 target エクスプレス eng base TRUE A 17.9216
## 20 17 target ストーブ eng base TRUE A 7.5882
## 21 20 target リコール eng base TRUE A 19.6667
## 22 21 target レター eng base TRUE A 82.6078
## 23 24 target ガッツ eng base TRUE A 23.7451
## 24 25 target バイク eng base TRUE A 25.8824
## 25 17 nonword ドートレギング eng <NA> FALSE <NA> NA
## 26 18 nonword フィスティレド eng <NA> FALSE <NA> NA
## 27 19 nonword ストネヘンデ eng <NA> FALSE <NA> NA
## 28 20 nonword ポリディフィエス eng <NA> FALSE <NA> NA
## 29 21 nonword メストレイヤーズ eng <NA> FALSE <NA> NA
## 30 22 nonword ドンスーン eng <NA> FALSE <NA> NA
## 31 23 nonword スプラム eng <NA> FALSE <NA> NA
## 32 24 nonword ティソベディエント eng <NA> FALSE <NA> NA
## 33 25 nonword ムイン eng <NA> FALSE <NA> NA
## 34 26 nonword ドソーム eng <NA> FALSE <NA> NA
## 35 27 nonword ヘイド eng <NA> FALSE <NA> NA
## 36 28 nonword オンテナー eng <NA> FALSE <NA> NA
## 37 29 nonword タンサック eng <NA> FALSE <NA> NA
## 38 30 nonword フロール eng <NA> FALSE <NA> NA
## 39 31 nonword アンチヒスタモーネ eng <NA> FALSE <NA> NA
## 40 32 nonword パラックス eng <NA> FALSE <NA> NA
## 41 33 nonword ハイプノジスト eng <NA> FALSE <NA> NA
## 42 34 nonword クロリエイジ eng <NA> FALSE <NA> NA
## 43 35 nonword コラプソス eng <NA> FALSE <NA> NA
## 44 36 nonword ビキナ eng <NA> FALSE <NA> NA
## 45 37 nonword スティメレーション eng <NA> FALSE <NA> NA
## 46 38 nonword スキマッド eng <NA> FALSE <NA> NA
## 47 39 nonword ディロクトネス eng <NA> FALSE <NA> NA
## 48 40 nonword ケグファグ eng <NA> FALSE <NA> NA
## freq_E
## 1 17.5744
## 2 21.4056
## 3 0.5272
## 4 0.5272
## 5 3.3743
## 6 20.8784
## 7 0.3163
## 8 11.7045
## 9 13.9541
## 10 2.4253
## 11 5.2020
## 12 3.6555
## 13 9.2793
## 14 31.5284
## 15 5.7292
## 16 2.2847
## 17 14.9382
## 18 40.7726
## 19 2.5307
## 20 3.5852
## 21 0.7030
## 22 3.5500
## 23 3.6906
## 24 13.8135
## 25 NA
## 26 NA
## 27 NA
## 28 NA
## 29 NA
## 30 NA
## 31 NA
## 32 NA
## 33 NA
## 34 NA
## 35 NA
## 36 NA
## 37 NA
## 38 NA
## 39 NA
## 40 NA
## 41 NA
## 42 NA
## 43 NA
## 44 NA
## 45 NA
## 46 NA
## 47 NA
## 48 NA
##
## [[3]]
## itemID type kana lang prime answer form freq_J
## 1 2 target インタビュー eng share TRUE A 29.5098
## 2 3 target コート eng spec TRUE A 100.7255
## 3 6 target エイリアン eng share TRUE A 17.4314
## 4 7 target アポイントメント eng spec TRUE A 30.5686
## 5 10 target スタンプ eng share TRUE A 5.9216
## 6 14 target チャンネル eng share TRUE A 24.4118
## 7 15 target クロール eng spec TRUE A 12.0392
## 8 18 target センス eng share TRUE A 131.8039
## 9 19 target ベンチ eng spec TRUE A 9.6667
## 10 22 target プロモーション eng share TRUE A 10.9216
## 11 23 target ツナ eng spec TRUE A 8.0000
## 12 1 target アイロン eng base TRUE A 17.9412
## 13 4 target グラウンド eng base TRUE A 72.4706
## 14 5 target アドレス eng base TRUE A 52.2745
## 15 8 target プレッシャー eng base TRUE A 53.1176
## 16 9 target プロポーズ eng base TRUE A 13.0000
## 17 12 target ボリューム eng base TRUE A 6.9412
## 18 13 target ベース eng base TRUE A 35.3725
## 19 16 target エクスプレス eng base TRUE A 17.9216
## 20 17 target ストーブ eng base TRUE A 7.5882
## 21 20 target リコール eng base TRUE A 19.6667
## 22 21 target レター eng base TRUE A 82.6078
## 23 24 target ガッツ eng base TRUE A 23.7451
## 24 25 target バイク eng base TRUE A 25.8824
## 25 17 nonword ドートレギング eng <NA> FALSE <NA> NA
## 26 18 nonword フィスティレド eng <NA> FALSE <NA> NA
## 27 19 nonword ストネヘンデ eng <NA> FALSE <NA> NA
## 28 20 nonword ポリディフィエス eng <NA> FALSE <NA> NA
## 29 21 nonword メストレイヤーズ eng <NA> FALSE <NA> NA
## 30 22 nonword ドンスーン eng <NA> FALSE <NA> NA
## 31 23 nonword スプラム eng <NA> FALSE <NA> NA
## 32 24 nonword ティソベディエント eng <NA> FALSE <NA> NA
## 33 25 nonword ムイン eng <NA> FALSE <NA> NA
## 34 26 nonword ドソーム eng <NA> FALSE <NA> NA
## 35 27 nonword ヘイド eng <NA> FALSE <NA> NA
## 36 28 nonword オンテナー eng <NA> FALSE <NA> NA
## 37 29 nonword タンサック eng <NA> FALSE <NA> NA
## 38 30 nonword フロール eng <NA> FALSE <NA> NA
## 39 31 nonword アンチヒスタモーネ eng <NA> FALSE <NA> NA
## 40 32 nonword パラックス eng <NA> FALSE <NA> NA
## 41 33 nonword ハイプノジスト eng <NA> FALSE <NA> NA
## 42 34 nonword クロリエイジ eng <NA> FALSE <NA> NA
## 43 35 nonword コラプソス eng <NA> FALSE <NA> NA
## 44 36 nonword ビキナ eng <NA> FALSE <NA> NA
## 45 37 nonword スティメレーション eng <NA> FALSE <NA> NA
## 46 38 nonword スキマッド eng <NA> FALSE <NA> NA
## 47 39 nonword ディロクトネス eng <NA> FALSE <NA> NA
## 48 40 nonword ケグファグ eng <NA> FALSE <NA> NA
## freq_E
## 1 17.5744
## 2 21.4056
## 3 0.5272
## 4 0.5272
## 5 3.3743
## 6 20.8784
## 7 0.3163
## 8 11.7045
## 9 13.9541
## 10 2.4253
## 11 5.2020
## 12 3.6555
## 13 9.2793
## 14 31.5284
## 15 5.7292
## 16 2.2847
## 17 14.9382
## 18 40.7726
## 19 2.5307
## 20 3.5852
## 21 0.7030
## 22 3.5500
## 23 3.6906
## 24 13.8135
## 25 NA
## 26 NA
## 27 NA
## 28 NA
## 29 NA
## 30 NA
## 31 NA
## 32 NA
## 33 NA
## 34 NA
## 35 NA
## 36 NA
## 37 NA
## 38 NA
## 39 NA
## 40 NA
## 41 NA
## 42 NA
## 43 NA
## 44 NA
## 45 NA
## 46 NA
## 47 NA
## 48 NA
このように,各行にすべての情報が入ってしまいます。よって,行ごとに入れることを考えないといけません。これを一発できれいにできたらかっこいいんですが,思いつかなかったので,とりあえずfor関数でi行目を取り出してtibbleに入れる,を繰り返すことにしました。まずは,dataのところがリスト型になるようにtibbleを作ります。
tibble::tibble(
pic=dat$pic,
word=dat$word,
data=list()
)->dat3
head(dat3)
しかしここでもまた失敗。dataの列の長さがあってないと怒られてしまいます。これを解決するためにlistの中に空のリストを入れます(正直ここで入れる要素はなんでもOK)。
tibble::tibble(
pic=dat$pic,
word=dat$word,
data=list(list())
)->dat3
dat3
## # A tibble: 48 x 3
## pic word data
## <fct> <fct> <list>
## 1 2_C_sh.jpg interview <list [0]>
## 2 3_C_sp.jpg court <list [0]>
## 3 6_C_sh.jpg alien <list [0]>
## 4 7_C_sp.jpg appointment <list [0]>
## 5 10_C_sh.jpg stamp <list [0]>
## 6 14_C_sh.jpg channel <list [0]>
## 7 15_C_sp.jpg crawl <list [0]>
## 8 18_C_sh.jpg sense <list [0]>
## 9 19_C_sp.jpg bench <list [0]>
## 10 22_C_sh.jpg promotion <list [0]>
## # … with 38 more rows
できあがった dat3 という変数の“data”列に,pic( dat の5列目)とword( dat の3列目)を除いたものを1行目から順にとってきてlistにして,それを dat3 の“data”列に順番にいれていきます。
for (i in 1:length(dat3$pic)){
dat3[i,3][[1]]<-list(dat[i,c(1,2,4,6,7,8,9,10,11)])
}
head(dat3)
## # A tibble: 6 x 3
## pic word data
## <fct> <fct> <list>
## 1 2_C_sh.jpg interview <df[,9] [1 × 9]>
## 2 3_C_sp.jpg court <df[,9] [1 × 9]>
## 3 6_C_sh.jpg alien <df[,9] [1 × 9]>
## 4 7_C_sp.jpg appointment <df[,9] [1 × 9]>
## 5 10_C_sh.jpg stamp <df[,9] [1 × 9]>
## 6 14_C_sh.jpg channel <df[,9] [1 × 9]>
こうすると,できあがったtibbleのdata列には1行目から順に,interview, court,…の刺激の情報が入ることになります。確認のために見てみましょう。
dat3$data[[1]];dat3$data[[2]]
## itemID type kana lang prime answer form freq_J freq_E
## 1 2 target インタビュー eng share TRUE A 29.5098 17.5744
## itemID type kana lang prime answer form freq_J freq_E
## 2 3 target コート eng spec TRUE A 100.7255 21.4056
ちゃんと入ってますね。最後に,このtibbleをJSON形式に変換すれば完成です。
toJSON(dat3)
## [{"pic":"2_C_sh.jpg","word":"interview","data":[{"itemID":2,"type":"target","kana":"インタビュー","lang":"eng","prime":"share","answer":true,"form":"A","freq_J":29.5098,"freq_E":17.5744}]},{"pic":"3_C_sp.jpg","word":"court","data":[{"itemID":3,"type":"target","kana":"コート","lang":"eng","prime":"spec","answer":true,"form":"A","freq_J":100.7255,"freq_E":21.4056}]},{"pic":"6_C_sh.jpg","word":"alien","data":[{"itemID":6,"type":"target","kana":"エイリアン","lang":"eng","prime":"share","answer":true,"form":"A","freq_J":17.4314,"freq_E":0.5272}]},{"pic":"7_C_sp.jpg","word":"appointment","data":[{"itemID":7,"type":"target","kana":"アポイントメント","lang":"eng","prime":"spec","answer":true,"form":"A","freq_J":30.5686,"freq_E":0.5272}]},{"pic":"10_C_sh.jpg","word":"stamp","data":[{"itemID":10,"type":"target","kana":"スタンプ","lang":"eng","prime":"share","answer":true,"form":"A","freq_J":5.9216,"freq_E":3.3743}]},{"pic":"14_C_sh.jpg","word":"channel","data":[{"itemID":14,"type":"target","kana":"チャンネル","lang":"eng","prime":"share","answer":true,"form":"A","freq_J":24.4118,"freq_E":20.8784}]},{"pic":"15_C_sp.jpg","word":"crawl","data":[{"itemID":15,"type":"target","kana":"クロール","lang":"eng","prime":"spec","answer":true,"form":"A","freq_J":12.0392,"freq_E":0.3163}]},{"pic":"18_C_sh.jpg","word":"sense","data":[{"itemID":18,"type":"target","kana":"センス","lang":"eng","prime":"share","answer":true,"form":"A","freq_J":131.8039,"freq_E":11.7045}]},{"pic":"19_C_sp.jpg","word":"bench","data":[{"itemID":19,"type":"target","kana":"ベンチ","lang":"eng","prime":"spec","answer":true,"form":"A","freq_J":9.6667,"freq_E":13.9541}]},{"pic":"22_C_sh.jpg","word":"promotion","data":[{"itemID":22,"type":"target","kana":"プロモーション","lang":"eng","prime":"share","answer":true,"form":"A","freq_J":10.9216,"freq_E":2.4253}]},{"pic":"23_C_sp.jpg","word":"tuna","data":[{"itemID":23,"type":"target","kana":"ツナ","lang":"eng","prime":"spec","answer":true,"form":"A","freq_J":8,"freq_E":5.202}]},{"pic":"1_C_b.jpg","word":"iron","data":[{"itemID":1,"type":"target","kana":"アイロン","lang":"eng","prime":"base","answer":true,"form":"A","freq_J":17.9412,"freq_E":3.6555}]},{"pic":"4_C_b.jpg","word":"ground","data":[{"itemID":4,"type":"target","kana":"グラウンド","lang":"eng","prime":"base","answer":true,"form":"A","freq_J":72.4706,"freq_E":9.2793}]},{"pic":"5_C_b.jpg","word":"address","data":[{"itemID":5,"type":"target","kana":"アドレス","lang":"eng","prime":"base","answer":true,"form":"A","freq_J":52.2745,"freq_E":31.5284}]},{"pic":"8_C_b.jpg","word":"pressure","data":[{"itemID":8,"type":"target","kana":"プレッシャー","lang":"eng","prime":"base","answer":true,"form":"A","freq_J":53.1176,"freq_E":5.7292}]},{"pic":"9_C_b.jpg","word":"propose","data":[{"itemID":9,"type":"target","kana":"プロポーズ","lang":"eng","prime":"base","answer":true,"form":"A","freq_J":13,"freq_E":2.2847}]},{"pic":"12_C_b.jpg","word":"volume","data":[{"itemID":12,"type":"target","kana":"ボリューム","lang":"eng","prime":"base","answer":true,"form":"A","freq_J":6.9412,"freq_E":14.9382}]},{"pic":"13_C_b.jpg","word":"base","data":[{"itemID":13,"type":"target","kana":"ベース","lang":"eng","prime":"base","answer":true,"form":"A","freq_J":35.3725,"freq_E":40.7726}]},{"pic":"16_C_b.jpg","word":"express","data":[{"itemID":16,"type":"target","kana":"エクスプレス","lang":"eng","prime":"base","answer":true,"form":"A","freq_J":17.9216,"freq_E":2.5307}]},{"pic":"17_C_b.jpg","word":"stove","data":[{"itemID":17,"type":"target","kana":"ストーブ","lang":"eng","prime":"base","answer":true,"form":"A","freq_J":7.5882,"freq_E":3.5852}]},{"pic":"20_C_b.jpg","word":"recall","data":[{"itemID":20,"type":"target","kana":"リコール","lang":"eng","prime":"base","answer":true,"form":"A","freq_J":19.6667,"freq_E":0.703}]},{"pic":"21_C_b.jpg","word":"letter","data":[{"itemID":21,"type":"target","kana":"レター","lang":"eng","prime":"base","answer":true,"form":"A","freq_J":82.6078,"freq_E":3.55}]},{"pic":"24_C_b.jpg","word":"guts","data":[{"itemID":24,"type":"target","kana":"ガッツ","lang":"eng","prime":"base","answer":true,"form":"A","freq_J":23.7451,"freq_E":3.6906}]},{"pic":"25_C_b.jpg","word":"bike","data":[{"itemID":25,"type":"target","kana":"バイク","lang":"eng","prime":"base","answer":true,"form":"A","freq_J":25.8824,"freq_E":13.8135}]},{"pic":"17_n.jpg","word":"dootlegging","data":[{"itemID":17,"type":"nonword","kana":"ドートレギング","lang":"eng","answer":false}]},{"pic":"18_n.jpg","word":"fistilled","data":[{"itemID":18,"type":"nonword","kana":"フィスティレド","lang":"eng","answer":false}]},{"pic":"19_n.jpg","word":"stonehende","data":[{"itemID":19,"type":"nonword","kana":"ストネヘンデ","lang":"eng","answer":false}]},{"pic":"20_n.jpg","word":"polidifies","data":[{"itemID":20,"type":"nonword","kana":"ポリディフィエス","lang":"eng","answer":false}]},{"pic":"21_n.jpg","word":"mestroyers","data":[{"itemID":21,"type":"nonword","kana":"メストレイヤーズ","lang":"eng","answer":false}]},{"pic":"22_n.jpg","word":"donsoon","data":[{"itemID":22,"type":"nonword","kana":"ドンスーン","lang":"eng","answer":false}]},{"pic":"23_n.jpg","word":"splum","data":[{"itemID":23,"type":"nonword","kana":"スプラム","lang":"eng","answer":false}]},{"pic":"24_n.jpg","word":"tisobedient","data":[{"itemID":24,"type":"nonword","kana":"ティソベディエント","lang":"eng","answer":false}]},{"pic":"25_n.jpg","word":"muin","data":[{"itemID":25,"type":"nonword","kana":"ムイン","lang":"eng","answer":false}]},{"pic":"26_n.jpg","word":"dothorme","data":[{"itemID":26,"type":"nonword","kana":"ドソーム","lang":"eng","answer":false}]},{"pic":"27_n.jpg","word":"hade","data":[{"itemID":27,"type":"nonword","kana":"ヘイド","lang":"eng","answer":false}]},{"pic":"28_n.jpg","word":"ontener","data":[{"itemID":28,"type":"nonword","kana":"オンテナー","lang":"eng","answer":false}]},{"pic":"29_n.jpg","word":"tansack","data":[{"itemID":29,"type":"nonword","kana":"タンサック","lang":"eng","answer":false}]},{"pic":"30_n.jpg","word":"frool","data":[{"itemID":30,"type":"nonword","kana":"フロール","lang":"eng","answer":false}]},{"pic":"31_n.jpg","word":"antihistamone","data":[{"itemID":31,"type":"nonword","kana":"アンチヒスタモーネ","lang":"eng","answer":false}]},{"pic":"32_n.jpg","word":"parracks","data":[{"itemID":32,"type":"nonword","kana":"パラックス","lang":"eng","answer":false}]},{"pic":"33_n.jpg","word":"hypnojist","data":[{"itemID":33,"type":"nonword","kana":"ハイプノジスト","lang":"eng","answer":false}]},{"pic":"34_n.jpg","word":"croilage","data":[{"itemID":34,"type":"nonword","kana":"クロリエイジ","lang":"eng","answer":false}]},{"pic":"35_n.jpg","word":"collapsos","data":[{"itemID":35,"type":"nonword","kana":"コラプソス","lang":"eng","answer":false}]},{"pic":"36_n.jpg","word":"bikina","data":[{"itemID":36,"type":"nonword","kana":"ビキナ","lang":"eng","answer":false}]},{"pic":"37_n.jpg","word":"stimelation","data":[{"itemID":37,"type":"nonword","kana":"スティメレーション","lang":"eng","answer":false}]},{"pic":"38_n.jpg","word":"skimmud","data":[{"itemID":38,"type":"nonword","kana":"スキマッド","lang":"eng","answer":false}]},{"pic":"39_n.jpg","word":"diroctness","data":[{"itemID":39,"type":"nonword","kana":"ディロクトネス","lang":"eng","answer":false}]},{"pic":"40_n.jpg","word":"kegfug","data":[{"itemID":40,"type":"nonword","kana":"ケグファグ","lang":"eng","answer":false}]}]
テキストファイルとして保存する場合は,以下のようにします。
toJSON(dat3) %>%
write(.,file = "json.txt")
おわりに
この記事では,データフレーム形式のものを階層性をもった形でJSON形式に変換するということをやってみました。tibbleという形式ができたことで,データフレームの中にリスト型変数を持つということができます。これができれば,あとは toJSON関数 で一発で変換ができました。もしかしたらもっとエレガントな方法もあるかもしれませんが,とりあえず現状の課題は解決できました。
なにをゆう たむらゆう。
おしまい。
- 注: 私はこれまで,大学院で習ったHot Soup Processorというゲームを作る目的で使われることが多いプログラミング言語を使って実験プログラムを作っていました。その際にも,特にRでのデータハンドリングに習熟するようになってからは,刺激を読み込む際に,その刺激の情報も一緒に読み込んで,実験結果の出力時にロング型で表示されるようにしていました。↩
