こんな感じのJSONをfromJSON()
で読み込むと、ちょっと特殊なdata.frameができることに気付いた(オプションをつければ挙動は変わるけど)。
df_from_json <- jsonlite::fromJSON('[ {"x": 1, "y": 1, "df": {"a": 10, "b": 10}}, {"x": 2, "y": 2, "df": {"a": 20, "b": 20}}, {"x": 3, "y": 3, "df": {"a": 30, "b": 30}} ]')
これはこんな感じでやれば作れる気がするし、実際、表示は同じものができる。
df_flattened <- data.frame( x = 1:3, y = 1:3, df = data.frame(a = 1:3 * 10, b = 1:3 * 10) ) df_from_json #> x y df.a df.b #> 1 1 1 10 10 #> 2 2 2 20 20 #> 3 3 3 30 30 df_flattened #> x y df.a df.b #> 1 1 1 10 10 #> 2 2 2 20 20 #> 3 3 3 30 30
でも、構造を見ると違っている。
str(df_from_json) #> 'data.frame': 3 obs. of 3 variables: #> $ x : int 1 2 3 #> $ y : int 1 2 3 #> $ df:'data.frame': 3 obs. of 2 variables: #> ..$ a: int 10 20 30 #> ..$ b: int 10 20 30 str(df_flattened) #> 'data.frame': 3 obs. of 4 variables: #> $ x : int 1 2 3 #> $ y : int 1 2 3 #> $ df.a: num 10 20 30 #> $ df.b: num 10 20 30
同じ構造のをつくるには、こんな感じであとから列を追加しないといけないみたい。
df_step_by_step <- data.frame( x = 1:3, y = 1:3 ) df_step_by_step$df <- data.frame(a = 1:3 * 10, b = 1:3 * 10) str(df_step_by_step) #> 'data.frame': 3 obs. of 3 variables: #> $ x : int 1 2 3 #> $ y : int 1 2 3 #> $ df:'data.frame': 3 obs. of 2 variables: #> ..$ a: num 10 20 30 #> ..$ b: num 10 20 30
でもこれはtibbleとしてはvalidではない。変換しようとしてもエラーになるし、
tibble::as_tibble(df_from_json) #> Error: Column `df` must be a 1d atomic vector or a list
さっきと同じであとから列を追加するやり方でやれば作れるけど、ちゃんと動作しない。
tbl_step_by_step <- tibble::tibble( x = 1:3, y = 1:3 ) tbl_step_by_step$df <- data.frame(a = 1:3 * 10, b = 1:3 * 10) tbl_step_by_step #> Error in `[.data.frame`(X[[i]], ...): undefined columns selected
たまーにfromJSON()
したdata.frameがdplyrでうまく扱えなくて、どうするのがいいんだろう、と思いつつ深追いしてなかったけどこういうことか...
お手軽な対処法としては、flatten = TRUE
なのかな。