我正在尝试从数据框中获取JSON数组对象,其中每个JSON对象都是数据框的子集
> x <- 1:5
> y <-c('a','b','c','d','e')
> z <-c(1,1,1,2,2)
> df <-data.frame(x,y,z)
> df
x y z
1 1 a 1
2 2 b 1
3 3 c 1
4 4 d 2
5 5 e 2
> rjson::toJSON(df)
[1] "{\"x\":[1,2,3,4,5],\"y\":[\"a\",\"b\",\"c\",\"d\",\"e\"],\"z\":[1,1,1,2,2]}"
> df1 = toJSONArray2(na.omit(df), json = F, names = F)
> rjson::toJSON(df1)
[1] "[[1,\"a\",1],[2,\"b\",1],[3,\"c\",1],[4,\"d\",2],[5,\"e\",2]]"
我需要的输出是
[[[1,a],[2,b],[3,c]],[[4,d],[5,e]]]
下面的方法我能够按预期获取数据帧列表,但无法获取所需的json输出。
> x <- foreach(i=1:2) %do% { subset(df,df$z==i)[c(1,2)]}
> x
[[1]]
x y
1 1 a
2 2 b
3 3 c
[[2]]
x y
4 4 d
5 5 e
找到了解决方案。
> x <- foreach(i=1:2) %do% {
tmp <-subset(df,df$z==i)[c(1,2)]
toJSONArray2(na.omit(tmp), json = F, names = F)
}
> rjson::toJSON(x)
我需要一个没有toJSONArray2的实现,这很慢
最佳答案
toJSONArray2
中的rCharts
函数很慢,主要是因为使用了RJSONIO
。我正在使用rjson
将其更新为更快的实现。这是我到目前为止所拥有的。我从orient
借用了pandas
参数的想法。
to_json = function(df, orient = "columns", json = T){
dl = as.list(df)
dl = switch(orient,
columns = dl,
records = do.call('zip_vectors_', dl),
values = do.call('zip_vectors_', setNames(dl, NULL))
)
if (json){
dl = rjson::toJSON(dl)
}
return(dl)
}
zip_vectors_ = function(..., names = F){
x = list(...)
y = lapply(seq_along(x[[1]]), function(i) lapply(x, pluck_(i)))
if (names) names(y) = seq_along(y)
return(y)
}
pluck_ = function (element){
function(x) x[[element]]
}
下面的示例将向您显示
to_json
比toJSONArray2
快20倍,其中大部分是由于使用了rjson
而不是RJSONIO
而引起的。N = 10^3
df <- data.frame(
x = rpois(N, 10),
y = sample(LETTERS, N, replace = T),
z = rpois(N, 5)
)
library(microbenchmark)
autoplot(microbenchmark(
to_json(df, orient = "values", json = T),
toJSONArray2(df, names = F),
times = 5
))
更新:在更仔细地阅读您的问题时,我意识到我们可以通过使用
dplyr
和to_json
进一步加快速度library(dplyr)
dfl = df %.%
group_by(z) %.%
do(function(x){
to_json(x[-3], orient = 'values', json = F)
})