将列表转换为data.frame时,R通过连接所有子列表名称自动命名变量。但是,当列表长度为1时,它似乎只保留姓氏。有没有办法为变量名强制执行完整路径名?
MWE:
> l <- list(a = list(b = 1), c = 2)
> l
$a
$a$b
[1] 1
$c
[1] 2
> data.frame(l)
b c
1 1 2
> ll <- list(a = list(b = 1, bb = 1), c = 2)
> data.frame(ll)
a.b a.bb c
1 1 1 2
在此,我希望将a.b
作为data.frame(l)
变量的名称,就像data.frame(ll)
一样。
答案 0 :(得分:2)
一种可能的解决方案是创建一个函数,将列表转换为as.data.frame()
的数据框,然后在第二步中将名称设置为所需的值:
list_df <- function(list) {
df <- as.data.frame(list)
names(df) <- list_names(list)
return (df)
}
显然,定义list_names()
是困难的部分。一种可能性是通过嵌套列表递归:
list_names <- function(list) {
recursor <- function(list, names) {
if (is.list(list)) {
new_names <- paste(names, names(list), sep = ".")
out <- unlist(mapply(list, new_names, FUN = recursor))
} else {
out <- names
}
return(out)
}
new_names <- unlist(mapply(list, names(list), FUN = recursor))
return(new_names)
}
这适用于您的两个例子:
l <- list(a = list(b = 1), c = 2)
ll <- list(a = list(b = 1, bb = 1), c = 2)
list_df(l)
## a.b c
## 1 1 2
list_df(ll)
## a.b a.bb c
## 1 1 1 2
它也适用于非嵌套的列表,以及具有更深嵌套的列表:
ls <- list(a = 1, b = 3)
lc <- list(a = list(b = 1, bb = 1), c = 2, d = list(e = list(f = 1, ff = 2), ee = list(fff = 5)))
list_df(ls)
## a b
## 1 1 3
list_df(lc)
## a.b a.bb c d.e.f d.e.ff d.ee.fff
## 1 1 1 2 1 2 5