将列表转换为数据框,同时保留列表元素名称

时间:2012-09-28 11:52:53

标签: r list dataframe r-faq

我有列表,其中元素名称是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

4 个答案:

答案 0 :(得分:16)

这是一种方式:

## 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()所需的次数。第二行只是将列表转换为矢量列表。

答案 1 :(得分:6)

使用reshape2melt,其方法为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

答案 2 :(得分:2)

已经发布的解决方案的一个优秀且仍然缺失的替代方案是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

同样使用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)

答案 3 :(得分:1)

使用基本功能的解决方案

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

如果您希望rownames为1,2,3,4,5,6,请尝试使用此{使用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