不确定如何简明扼要地说出我的问题,但现在就去了。
上下文:我想从数据帧中创建一个包含多个级别的json文件,因此我首先从我的数据帧构造一个嵌套列表。
# load libraries
library(RJSONIO)
# make data
dt <- data.frame(var1 = 1:4, var2 = c("a", "b", "c", "d"), var3 = c("foo", "bar", "foobar", "foobaz"), var4 = c(100, 200, 300, 400))
# make nested list
ll <- apply(dt, 1, function(x) list(id = x[['var1']], props = list(name = x[['var2']], altName = x[['var3']], height = x[['var4']])))
# output to JSON and print
js <- toJSON(ll); cat(js)
# output
[
{
"id": "1",
"props": {
"name": "a",
"altName": "foo",
"height": "100"
}
},
...
一切都按预期工作。但后来我想过滤数据帧,由于某种原因,R将我的初始列表嵌入到一个以行号命名的对象
# make nested list of dataframe from before but now filter on var1
dt <- dt[dt$var1 %% 2 == 0, ]
ll <- apply(dt, 1, function(x) list(id = x[['var1']], props = list(name = x[['var2']], altName = x[['var3']], height = x[['var4']])))
# output to JSON and print
js <- toJSON(ll); cat(js)
# output
{
"2": {
"id": "1",
"props": {
"name": "a",
"altName": "foo",
"height": "100"
}
}
},
...
现在,使用unname()
我可以删除名称2和4,但为什么会发生这种情况,是否有办法阻止列表的初始命名?一如往常,任何帮助表示赞赏!
答案 0 :(得分:0)
基本上发生的事情是你有一个不是子集的data.frame,它有一个特殊的row-name属性,只为每一行分配一个唯一的数字。但是当您进行子集时,该特殊值会被中断。请注意它如何保持原始索引2和4
dt[dt$var1 %% 2 == 0, ]
# var1 var2 var3 var4
# 2 2 b bar 200
# 4 4 d foobaz 400
这些会导致输出中的名称。您可以像使用unname()
一样删除这些行名称。同样,这不会发生在fill data.frame上,因为它们有一个“魔术”值,表示行的特殊名称,以节省内存空间。
但是在data.frame中运行apply
并且可能发生所有数据类型转换也很危险。另一种可能的策略是使用一些tidyverse库
library(tidyverse) # dplur, purrr, tidyr
library(jsonlite)
dt %>%
rename(id=var1, name=var2, altName=var3, height=var4) %>%
nest(-id, .key="props") %>%
mutate(props=map(props, unbox)) %>%
toJSON()