【R】JSON形式で刺激リスト作成

はじめに

この記事では,よくある刺激のリストを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形式で刺激を読み込むのですが,その際に,データに階層性が必要になってくるようです。別に,反応の取得だけを目的とするなら必要ないのですが,のちのデータ分析を楽にすることを考えると,これは実験の前の段階でやっておきたいです1jsPsychのページでは以下のように例が示されています。

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)

一応,各列に何が入っているかを簡単にまとめると,以下のようになります。

  1. itemID: 刺激のID(かぶりがありますが,nonwordは分析から最初に外すのでとりあえずOK。ほんとは連番のがいいですけど)
  2. type: 刺激の種類
  3. word: ターゲットとなる英単語
  4. kana: 対応するカタカナ語
  5. pic: 提示する画像
  6. lang: 提示する言語
  7. prime: プライミング条件
  8. answer: 正答
  9. form: フォーム
  10. freq_J: カタカナ語の頻度
  11. freq_E: 英単語の頻度

この実験では,まずはじめに画像を提示して,参加者はその画像を見ます。画像を理解したら次に注視点が表示されます。その後に提示された文字列が実在語かどうかを判断する語彙性判断課題です。プライミングの条件がshare, spec, baseと3条件あります。さて,プログラム上では,

  1. 画像(pic)を提示
  2. 語(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関数 で一発で変換ができました。もしかしたらもっとエレガントな方法もあるかもしれませんが,とりあえず現状の課題は解決できました。

なにをゆう たむらゆう。

おしまい。


  1. 注: 私はこれまで,大学院で習ったHot Soup Processorというゲームを作る目的で使われることが多いプログラミング言語を使って実験プログラムを作っていました。その際にも,特にRでのデータハンドリングに習熟するようになってからは,刺激を読み込む際に,その刺激の情報も一緒に読み込んで,実験結果の出力時にロング型で表示されるようにしていました。

コメントを残す