答えようとしている他の人のために、toJSONArray[2]
機能はrCharts
パッケージに含まれています。sapply
あなたのソリューションはかなりコンパクトですが、 andを使用してループを解除して少し締めることができますsplit
。
library(rjson)
library(rCharts)
x <- 1:5
y <- c('a', 'b' ,'c' ,'d' ,'e')
z <- c(1, 1, 1, 2, 2)
df <- data.frame(x, y, z)
toJSON(df)
out <- toJSONArray(sapply(split(df[,1:2], df$z), function(x) {
toJSONArray2(x, names=FALSE, json = FALSE)
}))
# doing gsub only for SO example output
cat(gsub("\\n", "", out))
## [ [ [ 1,"a" ],[ 2,"b" ],[ 3,"c" ] ],[ [ 4,"d" ],[ 5,"e" ] ] ]
toJSONArray[2]()
リクエスタごとに、 の関数の実装を見てみましょうrCharts
。
toJSONArray <- function(obj, json = TRUE, nonames = TRUE){
list2keyval <- function(l){
keys = names(l)
lapply(keys, function(key){
list(key = key, values = l[[key]])
})
}
obj2list <- function(df){
l = plyr::alply(df, 1, as.list)
if(nonames){ names(l) = NULL }
return(l)
}
if (json){
toJSON(obj2list(obj))
} else {
obj2list(obj)
}
}
toJSONArray2 <- function(obj, json = TRUE, names = TRUE, ...){
value = lapply(1:nrow(obj), function(i) {
res <- as.list(obj[i, ])
if (!names) names(res) <- NULL # remove names (e.g. {x = 1, y = 2} => {1, 2})
return(res)
})
if (json){
return(toJSON(value, .withNames = F, ...))
} else {
names(value) <- NULL;
return(value)
}
}
これらの関数はかなり最適化されていますが、toJSONArray2
基本的にapply
関数の 1 つをfor
ループとして使用しているため、必要に応じて JSON を自己エンコードする方が良いかどうかを見てみましょう。以下はあなたにとってより速いかもしれませんが、プロダクションコードのためにもう少し微調整する必要があります(そして、整数の引用符を外す必要がある場合):
out <- sapply(split(df[,1:2], df$z), function(x) {
out.2 <- apply(x, 1, function(y) {
return(paste0(toJSON(unlist(as.list(y)), .withNames = FALSE), sep=",", collapse=""))
})
out.2 <- paste(out.2, sep=", ", collapse=" ")
out.2 <- gsub(",$", "", out.2)
return(sprintf("[ %s ], ", out.2))
})
cat(sprintf("[ %s ]", gsub(", $", "", paste(unlist(out), collapse=""))))
## [ [ [ "1", "a" ], [ "2", "b" ], [ "3", "c" ] ], [ [ "4", "d" ], [ "5", "e" ] ] ]
実装と同様のパターンをいくつか共有していrCharts
ますが、要素分割されたデータ フレームの行を必要な形式に平手打ちすることに完全に焦点を当てています。