我想将列表列表转换为data.frame
。首先,我每个子列表的长度只有1,因此我使用了stack(as.data.frame(...))
但是堆栈没有接缝能够生成多列data.frame
。那么它是实现这一目标的最佳方式:
# works fine with only sublists of length 1
l = list(a = sample(1:5, 5), b = sample(1:5, 5))
> stack(as.data.frame(l))
values ind
1 5 a
2 4 a
3 1 a
4 2 a
5 3 a
6 2 b
7 1 b
8 3 b
9 5 b
10 4 b
现在我的列表是一个列表列表:
l = list(a = list(first = sample(1:5, 5), sec = sample(1:5, 5)), b = list(first = sample(1:5, 5), sec = sample(1:5, 5)))
stack(as.data.frame(l))
values ind
1 4 a.first
2 5 a.first
3 3 a.first
4 1 a.first
5 2 a.first
6 3 a.sec
7 5 a.sec
8 1 a.sec
9 2 a.sec
10 4 a.sec
11 5 b.first
12 4 b.first
13 3 b.first
14 1 b.first
15 2 b.first
16 3 b.sec
17 4 b.sec
18 1 b.sec
19 2 b.sec
20 5 b.sec
虽然我希望列ind
列a
和b
以及两列first
和sec
答案 0 :(得分:2)
我们可以通过连接(list
)嵌套元素('l1')来展平c
,从'{1}}获取'l1'('nm1'和''的子串nm2'),names
'l1'乘'nm1'(即通过删除前缀得到的子串),同时我们将'{1}}设置为'nm2'(通过删除后缀获得的子串)使用split
),循环浏览names
和.
它('lst')。然后,我们list
'ind'列(在所有stack
元素中都是相同的,因此我们从第一个列表元素 - cbind
)获取它,其中包含'value'列,即第一栏。
list
或者使用lst[[1]][2]
我们可以获得预期的输出。
l1 <- do.call(c, l)
nm1 <- sub("[^.]+\\.", "", names(l1))
nm2 <- sub("\\..*", "", names(l1))
lst <- lapply(split(setNames(l1, nm2), nm1), stack)
cbind(lst[[1]][2],lapply(lst, `[[`, 1))
# ind first sec
#1 a 1 1
#2 a 5 5
#3 a 4 4
#4 a 3 3
#5 a 2 2
#6 b 3 4
#7 b 4 5
#8 b 2 2
#9 b 1 3
#10 b 5 1
答案 1 :(得分:1)
这是另一种方法:
df <- stack(as.data.frame(l))
# split names of variables
indVars <- strsplit(as.character(df$ind), split="\\.")
# add variables to data.frame
df$letters <- sapply(indVars, function(i) i[1])
df$order <- sapply(indVars, function(i) i[2])
# get final data.frame
cbind("order"=unstack(df, letters~order)[,1], unstack(df, values~order))