快速将多行数据转换为JSON字符串

4
我有大约15个包含10万至30万行的data.frame。我想通过变量v将其他列压缩成字符json格式以节省存储空间。请注意,v中的每个组都将有多行(1行或更多;可能更多)。我下面的代码使用了jsonlite包来转换,但由于我设置的拆分方式,它很慢且不够高效。如何更快、更高效地完成此任务?我不需要使用jsonlite包,只是因为这是我唯一知道的方法。我认为可以用data.table直接快速生成字符json,但无法想到具体实现方法。

附言:如果了解我的动机会有所帮助……我这样做是为了拥有一个哈希表,我可以在其中查找v,然后将json转换回R data.frame。也许有一种比我现在用的更直接的方法可以使用jsonlite,但toJSON(dat)并不是我想要的。

最小工作示例(MWE)

set.seed(10)

dat <- data.frame(
    v = rep(c('red', 'blue'), each =3),
    w = sample(LETTERS, 6),
    x = sample(1:3, 6, T),
    y = sample(1:3, 6, T),
    z = sample(1:3, 6, T),
    stringsAsFactors = FALSE
)

dat

数据视图

     v w x y z
1  red N 1 1 2
2  red H 1 2 3
3  red K 2 2 3
4 blue P 2 2 2
5 blue B 2 1 3
6 blue E 2 1 2

转换

library(jsonlite)
jsonlist <- lapply(split(dat[-1], dat$v), function(x) as.character(toJSON(x)))

data.frame(
    v = names(jsonlist),
    json = unlist(jsonlist, use.names=FALSE),
    stringsAsFactors = FALSE
)

期望结果

      v                                                                                  json
1 blue [{"w":"P","x":2,"y":2,"z":2},{"w":"B","x":2,"y":1,"z":3},{"w":"E","x":2,"y":1,"z":2}]
2  red [{"w":"N","x":1,"y":1,"z":2},{"w":"H","x":1,"y":2,"z":3},{"w":"K","x":2,"y":2,"z":3}]
2个回答

6
使用data.table,您可以按v进行分组,并将.SD传递给toJSON
library(data.table)
setDT(dat)
dat[, toJSON(.SD), by = v]
#      v                                                                                    V1
#1:  red [{"w":"N","x":1,"y":1,"z":2},{"w":"H","x":1,"y":2,"z":3},{"w":"K","x":2,"y":2,"z":3}]
#2: blue [{"w":"P","x":2,"y":2,"z":2},{"w":"B","x":2,"y":1,"z":3},{"w":"E","x":2,"y":1,"z":2}]

1

我还不确定你所做的事情是否有意义,但是:

dat %>%
  group_by(v) %>%
  do(json = select(., -v) %>% toJSON ) %>%
  mutate(json = unlist(json))

这里的 . 并不是你想象中的那样。它似乎只是在 do() 中引用子集。 - Arun
@bramtayl,你有更合理的替代方案吗?这是一个标准查找。我想要访问v中的信息,而不是先扩展数据,只有在查找v之后再扩展它。这将大大减少初始搜索的行数(从1000万减少到100万)。 - Tyler Rinker
我认为上面的编辑应该可以工作。然而,我猜想使用 data.table 的解决方案会更快。 - bramtayl
@bramtayl,我是在参考您的评论,您不确定它是否有意义。什么会有意义呢? - Tyler Rinker
1
如果您正在使用data.table,似乎最好保留原始数据集并将v设置为键。这将使按v子集非常快速。 - bramtayl
此外,如果您有15个具有相同变量的数据集,将它们放在一个大数据集中是最合理的。您可以将它们放入列表中,并使用dplyr bind_rows(.id = "dataset_number")或data.table等效方法。 - bramtayl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接