提问人:ego_ 提问时间:9/28/2012 最后编辑:Jaapego_ 更新时间:1/20/2018 访问量:15842
将列表转换为数据框,同时保留列表元素名称
Convert list to data frame while keeping list-element names
问:
我有列表,其中元素名称是 ID 标签,并包含一个带有数值的向量。它们的长度不等(!)。
我想将其转换为一个数据框,其中 ID 位于一列中,数值位于另一列中。例如:
$`1`
[1] 1 2
$`2`
[1] 1 2 3
$`3`
[1] 1
自:
ID Obs
1 1
1 2
2 1
2 2
2 3
3 1
答:
10赞
mnel
9/28/2012
#1
Use 和 which 有一个方法reshape2
melt
melt.list
.list <- list(`1` = 1:2, `2` = 1:3, `3` = 1:2)
library(reshape2)
melt(.list)
## value L1
## 1 1 1
## 2 2 1
## 3 1 2
## 4 2 2
## 5 3 2
## 6 1 3
## 7 2 3
1赞
Jilber Urbina
9/28/2012
#2
使用基本函数的解决方案
List <- list('1'=c(1,2), '2'= c(1,2,3), '3'=1)
x <- unlist(List) # as suggested by Gavin Simpson
data.frame(ID=substr(names(x),1,1), Obs=x)
ID Obs
11 1 1
12 1 2
21 2 1
22 2 2
23 2 3
3 3 1
如果你想是 1,2,3,4,5,6,试试这个(使用):rownames
setNames
data.frame(ID=substr(names(x),1,1), Obs=setNames(x, NULL))
ID Obs
1 1 1
2 1 2
3 2 1
4 2 2
5 2 3
6 3 1
只有当所有名称的长度都相同时,此解决方案才有效,否则它将失败,并且最好使用 Gavin 的解决方案。例如,请参阅:
List2 <- list('week1'=c(1,2), 'week2'= c(1,2,3), 'week3'=1)
x <- unlist(List2)
data.frame(ID=substr(names(x),1,nchar(names(x)[1])-1), Obs=setNames(x, NULL))
ID Obs
1 week1 1
2 week1 2
3 week2 1
4 week2 2
5 week2 3
6 week3 1
评论
0赞
Gavin Simpson
9/28/2012
我想你可以做到,不是吗?x <- unlist(List)
0赞
Jilber Urbina
9/28/2012
@Gavin辛普森,你是对的,现在我刚刚编辑了我的答案,包括你的评论。
0赞
ego_
9/28/2012
似乎当我取消列出时,它会在元素名称中添加一个数字,导致脚本的其余部分因我的目的而失败:S
0赞
ego_
9/28/2012
@Jilber抱歉,但现在它将所有名称更改为“2”或“5”。元素名称是由 ID.Seasons.Week 组成的因子,例如 2225.Winter.1(如果有帮助的话)。我喜欢尽可能使用基本功能的角度,所以如果这也行得通,那就太好了。
21赞
Gavin Simpson
9/28/2012
#3
这是一种方法:
## your list
ll <- list("1" = 1:2, "2" = 1:3, "3" = 1:2)
## convert to data.frame
dl <- data.frame(ID = rep(names(ll), sapply(ll, length)),
Obs = unlist(ll))
这给出了:
> dl
ID Obs
11 1 1
12 1 2
21 2 1
22 2 2
23 2 3
31 3 1
32 3 2
调用中的第一行只是一些代码,用于重复列表所需的次数。第二行只是取消列出将其转换为向量的列表。data.frame()
names()
评论
0赞
ego_
9/28/2012
我给了你正确的答案,因为你的方法最快: <br/> > system.time(melt(X))<br/> 用户系统已用 <br/> 3.12 0.11 3.24 <br/> > system.time(data.frame(ID = rep(names(X), sapply(X, length)), Obs = unlist(X)))<br/> 用户系统已用 <br/> 0.08 0.00 0.07<br/>
0赞
ego_
9/28/2012
我似乎不能添加换行符,对不起,一团糟:S
0赞
sebastian-c
7/20/2023
您可以使用来避免 .lengths
rep(sapply())
0赞
Gavin Simpson
7/21/2023
@sebastian-c 好点,我认为在 2012 年不是语言的一部分,但现在会更好。lengths()
7赞
Jaap
1/16/2018
#4
对于已经发布的解决方案,一个很好的但仍然缺失的替代方案是 -function:stack
df <- stack(ll)[2:1]
这给了:
> df ind values 1 1 1 2 1 2 3 2 1 4 2 2 5 2 3 6 3 1 7 3 2
使用 as 也可以获得确切所需的格式:setNames
df <- setNames(stack(ll)[2:1], c('ID','Obs'))
这给了:
> df ID Obs 1 1 1 2 1 2 3 2 1 4 2 2 5 2 3 6 3 1 7 3 2
使用的数据:
ll <- list("1" = 1:2, "2" = 1:3, "3" = 1:2)
上一个:对数据框中组内的行进行编号
下一个:变量前的美元符号
评论