1

我有一个简单的 JSON 文件,我试图将其强制转换为 R data.frame。

json = "
{ \"objects\":
  {
    \"object_one\": {
      \"key1\"        : \"value1\",
      \"key2\"        : \"value2\",
      \"key3\"        : \"0\",
      \"key4\"        : \"value3\",
      \"key5\"        : \"False\",
      \"key6\"        : \"False\"
    },

    \"object_two\": {
      \"key1\"        : \"0.5\",
      \"key2\"        : \"0\",
      \"key3\"        : \"343\",
      \"key4\"        : \"value4\",
      \"key5\"        : \"True\",
      \"key6\"        : \"True\"
    }
  }
}
"

我只想将每个对象的名称提取为索引键(或行名),从键创建列名并传播值。

不幸的是,我没有运气取消语法。任何人都可以帮忙吗?

谢谢

斯图尔特

4

2 回答 2

2

使用 tidyjson 有两种方法可以做到这一点,第一种是使用tidyjson::append_values_stringthen tidyr::spread

library(tidyjson)
library(dplyr)
library(tidyr)
json %>% 
  enter_object("objects") %>% 
  gather_keys("object") %>% 
  gather_keys("key") %>% 
  append_values_string("value") %>% 
  tbl_df %>% spread(key, value)

#> # A tibble: 2 x 8
#>   document.id     object   key1   key2  key3   key4  key5  key6
#> *       <int>      <chr>  <chr>  <chr> <chr>  <chr> <chr> <chr>
#> 1           1 object_one value1 value2     0 value3 False False
#> 2           1 object_two    0.5      0   343 value4  True  True    

另一种方法是分别用于tidyjson::spread_values指定每个键:

json %>%
  enter_object("objects") %>%
  gather_keys("object") %>%
  spread_values(
    key1 = jstring("key1"),
    key2 = jstring("key2"),
    key3 = jnumber("key3"),
    key4 = jstring("key4"),
    key5 = jstring("key5"),
    key6 = jstring("key6")
  )

#>   document.id     object   key1   key2 key3   key4  key5  key6
#> 1           1 object_one value1 value2    0 value3 False False
#> 2           1 object_two    0.5      0  343 value4  True  True

第二种方法的优点是,您可以 (a) 指定每列的类型,并且 (b) 即使某些文档或对象中的键发生更改(或丢失),也可以保证获得相同的 data.frame 结构。

于 2016-08-29T20:22:24.953 回答
1

不完全确定您想要的输出,但您可以使用它jsonlite::fromJSON来提取数据,data.table::rbindlist并将其放入data.table

library(jsonlite)
library(data.table)

rbindlist(fromJSON(json))

#     object_one object_two
# 1:     value1        0.5
# 2:     value2          0
# 3:          0        343
# 4:     value3     value4
# 5:      False       True
# 6:      False       True

根据您的评论,另一种涉及一些重塑的方法

library(jsonlite)
library(reshape2)

lst <- fromJSON(json)
lst <- lapply(lst[[1]], unlist)

df <- as.data.frame(lst)
df$key <- rownames(df)

df <- melt(df, id = "key")
df <- dcast(df, formula = variable ~ key)
df
#      variable   key1   key2 key3   key4  key5  key6
# 1 object_one value1 value2    0 value3 False False
# 2 object_two    0.5      0  343 value4  True  True
于 2016-05-26T04:41:17.003 回答