从data.frame清除列表,没有行号的名称

时间:2018-06-12 19:16:55

标签: r

不确定如何简明扼要地说出我的问题,但现在就去了。

上下文:我想从数据帧中创建一个包含多个级别的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,但为什么会发生这种情况,是否有办法阻止列表的初始命名?一如往常,任何帮助表示赞赏!

1 个答案:

答案 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()