Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
格式化来自R的JSON输出的策略_Json_R_Dataframe - Fatal编程技术网

格式化来自R的JSON输出的策略

格式化来自R的JSON输出的策略,json,r,dataframe,Json,R,Dataframe,我正在试图找出从R生成JSON文件的最佳方法。在R中,我有以下数据帧tmp > tmp gender age welcoming proud tidy unique 1 1 30 4 4 4 4 2 2 34 4 2 4 4 3 1 34 5 3 4 5 4 2 33 2 3 2

我正在试图找出从R生成JSON文件的最佳方法。在
R
中,我有以下数据帧
tmp

> tmp
  gender age welcoming proud tidy unique
1      1  30         4     4    4      4
2      2  34         4     2    4      4
3      1  34         5     3    4      5
4      2  33         2     3    2      4
5      2  28         4     3    4      4
6      2  26         3     2    4      3
dput(tmp)
的输出如下:

tmp <- structure(list(gender = c(1L, 2L, 1L, 2L, 2L, 2L), age = c(30, 
34, 34, 33, 28, 26), welcoming = c(4L, 4L, 5L, 2L, 4L, 3L), proud = c(4L, 
2L, 3L, 3L, 3L, 2L), tidy = c(4L, 4L, 4L, 2L, 4L, 4L), unique = c(4L, 
4L, 5L, 4L, 4L, 3L)), .Names = c("gender", "age", "welcoming", 
"proud", "tidy", "unique"), na.action = structure(c(15L, 39L, 
60L, 77L, 88L, 128L, 132L, 172L, 272L, 304L, 305L, 317L, 328L, 
409L, 447L, 512L, 527L, 605L, 618L, 657L, 665L, 670L, 708L, 709L, 
729L, 746L, 795L, 803L, 826L, 855L, 898L, 911L, 957L, 967L, 983L, 
984L, 988L, 1006L, 1161L, 1162L, 1224L, 1245L, 1256L, 1257L, 
1307L, 1374L, 1379L, 1386L, 1387L, 1394L, 1401L, 1408L, 1434L, 
1446L, 1509L, 1556L, 1650L, 1717L, 1760L, 1782L, 1814L, 1847L, 
1863L, 1909L, 1930L, 1971L, 2004L, 2022L, 2055L, 2060L, 2065L, 
2082L, 2109L, 2121L, 2145L, 2158L, 2159L, 2226L, 2227L, 2281L
), .Names = c("15", "39", "60", "77", "88", "128", "132", "172", 
"272", "304", "305", "317", "328", "409", "447", "512", "527", 
"605", "618", "657", "665", "670", "708", "709", "729", "746", 
"795", "803", "826", "855", "898", "911", "957", "967", "983", 
"984", "988", "1006", "1161", "1162", "1224", "1245", "1256", 
"1257", "1307", "1374", "1379", "1386", "1387", "1394", "1401", 
"1408", "1434", "1446", "1509", "1556", "1650", "1717", "1760", 
"1782", "1814", "1847", "1863", "1909", "1930", "1971", "2004", 
"2022", "2055", "2060", "2065", "2082", "2109", "2121", "2145", 
"2158", "2159", "2226", "2227", "2281"), class = "omit"), row.names = c(NA, 
6L), class = "data.frame")
我还试验了
RJSONIO
包;
toJSON()
的输出是相同的。我想制作以下结构:

  {"traits":["gender","age","welcoming","proud", "tidy", "unique"],
   "values":[   
            {"gender":1,"age":30,"welcoming":4,"proud":4,"tidy":4, "unique":4},
            {"gender":2,"age":34,"welcoming":4,"proud":2,"tidy":4, "unique":4},
            ....
            ]
我不知道怎样才能最好地做到这一点。我意识到我可以使用
python
逐行解析它,但我觉得可能有更好的方法。我还意识到,
R
中的数据结构并不反映我的
JSON
文件(特别是
traits
行)中所需的元信息,但我主要感兴趣的是生成格式类似于该行的数据

{"gender":1,"age":30,"welcoming":4,"proud":4,"tidy":4, "unique":4}
因为我可以手动添加第一行


编辑:我发现了一篇有用的文章,作者处理了一个类似的问题并提供了解决方案。此函数用于从数据帧生成格式化的JSON文件

toJSONarray <- function(dtf){
clnms <- colnames(dtf)

name.value <- function(i){
quote <- '';
# if(class(dtf[, i])!='numeric'){
if(class(dtf[, i])!='numeric' && class(dtf[, i])!= 'integer'){ # I modified this line so integers are also not enclosed in quotes
quote <- '"';
}

paste('"', i, '" : ', quote, dtf[,i], quote, sep='')
}

objs <- apply(sapply(clnms, name.value), 1, function(x){paste(x, collapse=', ')})
objs <- paste('{', objs, '}')

# res <- paste('[', paste(objs, collapse=', '), ']')
res <- paste('[', paste(objs, collapse=',\n'), ']') # added newline for formatting output

return(res)
}

toJSONarray在我看来,您可以通过使用适当的
apply
语句将
data.frame
的每一行发送到JSON来实现这一点

对于单行:

library(RJSONIO)

> x <- toJSON(tmp[1, ])
> cat(x)
{
 "gender": 1,
"age":     30,
"welcoming": 4,
"proud": 4,
"tidy": 4,
"unique": 4 
}

基于Andrie关于
apply
的想法,在调用
toJSON
之前,您可以通过修改
tmp
变量来获得所需的内容

library(RJSONIO)
modified <- list(
  traits = colnames(tmp),
  values = unname(apply(tmp, 1, function(x) as.data.frame(t(x))))
)
cat(toJSON(modified))
库(RJSONIO)

修改后的基于安德烈和里奇的想法,使用
alply
而不是
apply
避免将数字转换为字符:

library(RJSONIO)
library(plyr)
modified <- list(
  traits = colnames(tmp),
  values = unname(alply(tmp, 1, identity))
)
cat(toJSON(modified))

然后将此代码(使用
alply
)与另一个示例(使用
apply
)进行比较。

另一个选项是使用
split
将包含N行的
数据.frame
拆分为包含1行的N个数据.frames

library(RJSONIO)
modified <- list(
   traits = colnames(tmp),
   values = split(tmp, seq_len(nrow(tmp)))
)
cat(toJSON(modified))
库(RJSONIO)

使用包
jsonlite
修改:

> jsonlite::toJSON(list(traits = names(tmp), values = tmp), pretty = TRUE)
{
  "traits": ["gender", "age", "welcoming", "proud", "tidy", "unique"],
  "values": [
    {
      "gender": 1,
      "age": 30,
      "welcoming": 4,
      "proud": 4,
      "tidy": 4,
      "unique": 4
    },
    {
      "gender": 2,
      "age": 34,
      "welcoming": 4,
      "proud": 2,
      "tidy": 4,
      "unique": 4
    },
    {
      "gender": 1,
      "age": 34,
      "welcoming": 5,
      "proud": 3,
      "tidy": 4,
      "unique": 5
    },
    {
      "gender": 2,
      "age": 33,
      "welcoming": 2,
      "proud": 3,
      "tidy": 2,
      "unique": 4
    },
    {
      "gender": 2,
      "age": 28,
      "welcoming": 4,
      "proud": 3,
      "tidy": 4,
      "unique": 4
    },
    {
      "gender": 2,
      "age": 26,
      "welcoming": 3,
      "proud": 2,
      "tidy": 4,
      "unique": 3
    }
  ]
} 

谢谢@Andrie,这是个好主意。我想知道如何在每一行的末尾插入一个
,使用类似这样的东西:
x刚刚想出来:
x@celenius:这看起来很可疑,就像你试图自己编写一些JSON,结果只会落泪。最好将数据操纵成一种形式,在这种形式中调用
toJSON
可以提供您想要的内容。请看我的答案。@RichieCotton我刚才在
{…}{…}
之间添加了一个
。生成的输出不是有效的JSON。虽然我大体上同意,但这可能不是一种可靠的方法。图书馆RJSONIO给了我一个我还没有解决的问题。所有值都作为1的数组输出。e、 g.{“性别”:[2],“年龄”:[33]}。。。。但是,jsonlite::toJSON()生成了预期的输出。{“性别”:2,“年龄”:33}。我通过ddply(…Summary…)创建数据,但我也尝试使用简单的data.frame(a=c(1,2,3),b=(“a”,“b”,“c”))并得到了相同的结果。这两种方法(
rjson
RJSONIO
)的一个问题是它们将所有数字转换为字符串。例如,
2
变为
“2”
。作为问题的一部分,我粘贴的代码片段避免了这个问题,因为它检查
numeric
integer
。也许我应该加上它作为答案。@celenius:我应用于变量
tmp
的解决方案是整数,而不是字符串整数。你确定你没有做傻事吗?@RichieCotton嗯。我一定是做了傻事——当我第一次尝试时,它肯定是以字符串形式返回整数。不知道为什么,就像我刚才运行它时一样,它工作得很好(整数就是整数)。我没有覆盖
toJSON
函数。嗨,亚历克斯-我最喜欢这个答案。jsonlite不需要上面@civilstat answer中描述的alply()/apply()转换就可以理解data.frame和输出。另外-我遇到了RJSONIO的一个问题,我无法解决这个问题,导致所有值都是1的数组。jsonlite没有这个问题。谢谢你的反馈,我很高兴你发现它很有用。这个问题问到现在已经很多年了。我建议你看看图书馆(jsonlite)——下面是别人提供的答案。它不需要apply()转换,直接生成预期的JSON输出。@ripvlan-标记jsonlite作为答案
tmp$grade <- c("A","B","C","D","E","F")
library(RJSONIO)
modified <- list(
   traits = colnames(tmp),
   values = split(tmp, seq_len(nrow(tmp)))
)
cat(toJSON(modified))
> jsonlite::toJSON(list(traits = names(tmp), values = tmp), pretty = TRUE)
{
  "traits": ["gender", "age", "welcoming", "proud", "tidy", "unique"],
  "values": [
    {
      "gender": 1,
      "age": 30,
      "welcoming": 4,
      "proud": 4,
      "tidy": 4,
      "unique": 4
    },
    {
      "gender": 2,
      "age": 34,
      "welcoming": 4,
      "proud": 2,
      "tidy": 4,
      "unique": 4
    },
    {
      "gender": 1,
      "age": 34,
      "welcoming": 5,
      "proud": 3,
      "tidy": 4,
      "unique": 5
    },
    {
      "gender": 2,
      "age": 33,
      "welcoming": 2,
      "proud": 3,
      "tidy": 2,
      "unique": 4
    },
    {
      "gender": 2,
      "age": 28,
      "welcoming": 4,
      "proud": 3,
      "tidy": 4,
      "unique": 4
    },
    {
      "gender": 2,
      "age": 26,
      "welcoming": 3,
      "proud": 2,
      "tidy": 4,
      "unique": 3
    }
  ]
}