rjson :: fromJSON只返回第一个项

时间:2018-02-14 22:10:36

标签: json r database sqlite rjson

我有一个包含多个列的sqlite数据库文件。其中一列中嵌入了JSON字典(带有两个键)。我想将JSON列提取到R中的数据框,该数据框在单独的列中显示每个键。

我尝试过rjson :: fromJSON,但它只读取第一项。有没有我失踪的伎俩?

这是一个模仿我问题的例子:

> eg <- as.vector(c("{\"3x\": 20, \"6y\": 23}", "{\"3x\": 60, \"6y\": 50}"))
> fromJSON(eg)

$ 3x [1] 20

$ 6y [1] 23

所需的输出类似于:

# a data frame for both variables
  3x 6y
1 20 23
2 60 50

,或者

# a data frame for each variable
  3x 
1 20
2 60

  6y
1 23
2 50

1 个答案:

答案 0 :(得分:1)

您所寻找的实际上是lapply和某些rbind或相关应用的组合。

我会稍微扩展您的数据,只是为了拥有超过2个元素。

eg <- c("{\"3x\": 20, \"6y\": 23}",
        "{\"3x\": 60, \"6y\": 50}",
        "{\"3x\": 99, \"6y\": 72}")

library(jsonlite)

使用基数R,我们可以

do.call(rbind.data.frame, lapply(eg, fromJSON))
#   X3x X6y
# 1  20  23
# 2  60  50
# 3  99  72

您可能会尝试执行Reduce(rbind, lapply(eg, fromJSON))之类的操作,但值得注意的是,在Reduce模型中,rbind被称为&#34; N-1&#34;时间,地点&#34; N&#34;是eg中的元素数量;这导致了大量的数据复制,虽然它可能会很好地用于小型的N&#34;但它的扩展性可怕。使用do.call选项,rbind只调用一次。

请注意,列标签已经过R-ized,因为data.frame列名称不应以数字开头。 (有可能,但通常不鼓励。)

如果您确信所有子串都具有完全相同的元素,那么您在这里可能会很好。如果有可能在某个时候出现差异,也许

eg <- c(eg, "{\"3x\": 99}")

然后您会注意到基本R解决方案默认不再有效。

do.call(rbind.data.frame, lapply(eg, fromJSON))
# Error in (function (..., deparse.level = 1, make.row.names = TRUE, stringsAsFactors = default.stringsAsFactors())  : 
#   numbers of columns of arguments do not match

可能有一些技巧可以尝试对元素进行规范化,以确保匹配。但是,如果您不反对tidyverse包裹:

library(dplyr)
eg2 <- bind_rows(lapply(eg, fromJSON))
eg2
# # A tibble: 4 × 2
#    `3x`  `6y`
#   <int> <int>
# 1    20    23
# 2    60    50
# 3    99    72
# 4    99    NA

虽然您不能直接使用美元方法调用它,但您仍然可以使用[[或反引号。

eg2$3x
# Error: unexpected numeric constant in "eg2$3"
eg2[["3x"]]
# [1] 20 60 99 99
eg2$`3x`
# [1] 20 60 99 99