在用R语言处理数据的过程中,我经常会遇到list和dataframe数据格式之间的转换,一般是需要把list转换为dataframe的情况居多。一直以来我也没有好好研究两者的转换关系,通常都是碰到一次花时间解决一次,不知道有没有和我一样的小伙伴。
这期推文比较系统的研究了list与dataframe转换的转换关系,希望能够对大家有所帮助,节约大家一些时间。
dataframe转换为list
> # 加载鸢尾花数据集
> data("iris")
> # 数据框转换为列表-----------------------------------------------------
> data <- iris[1:5,]
> dataSepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
4 4.6 3.1 1.5 0.2 setosa
5 5.0 3.6 1.4 0.2 setosa
> list1 <- as.list(data)
> list1
$Sepal.Length
[1] 5.1 4.9 4.7 4.6 5.0$Sepal.Width
[1] 3.5 3.0 3.2 3.1 3.6$Petal.Length
[1] 1.4 1.4 1.3 1.5 1.4$Petal.Width
[1] 0.2 0.2 0.2 0.2 0.2$Species
[1] setosa setosa setosa setosa setosa
Levels: setosa versicolor virginica
list转换为dataframe
可以归纳为以下几种情形:
(1)向量——单层列表,列表的元素为向量
> ## (1)向量--------------------------------------
> list1 <- list(a=iris$Sepal.Length[1:5],
+ b=iris$Sepal.Width[1:5],
+ c=iris$Petal.Length[1:5])
> list1
$a
[1] 5.1 4.9 4.7 4.6 5.0$b
[1] 3.5 3.0 3.2 3.1 3.6$c
[1] 1.4 1.4 1.3 1.5 1.4> # 3个向量按列合并
> as.data.frame(list1)a b c
1 5.1 3.5 1.4
2 4.9 3.0 1.4
3 4.7 3.2 1.3
4 4.6 3.1 1.5
5 5.0 3.6 1.4
> dplyr::bind_rows(list1)
# A tibble: 5 × 3a b c<dbl> <dbl> <dbl>
1 5.1 3.5 1.4
2 4.9 3 1.4
3 4.7 3.2 1.3
4 4.6 3.1 1.5
5 5 3.6 1.4
(2)数据框——单层列表,列表的元素为数据框
> ## (2)数据框------------------------------------
> list2 <- list(a=iris[1:2,],b=iris[6:7,],c=iris[11:12,])
> list2
$aSepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa$bSepal.Length Sepal.Width Petal.Length Petal.Width Species
6 5.4 3.9 1.7 0.4 setosa
7 4.6 3.4 1.4 0.3 setosa$cSepal.Length Sepal.Width Petal.Length Petal.Width Species
11 5.4 3.7 1.5 0.2 setosa
12 4.8 3.4 1.6 0.2 setosa> # 3个数据框按行合并
> dplyr::bind_rows(list2) Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 5.4 3.9 1.7 0.4 setosa
4 4.6 3.4 1.4 0.3 setosa
5 5.4 3.7 1.5 0.2 setosa
6 4.8 3.4 1.6 0.2 setosa
> # 3个数据框按行合并
> data.table::rbindlist(list2)Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1: 5.1 3.5 1.4 0.2 setosa
2: 4.9 3.0 1.4 0.2 setosa
3: 5.4 3.9 1.7 0.4 setosa
4: 4.6 3.4 1.4 0.3 setosa
5: 5.4 3.7 1.5 0.2 setosa
6: 4.8 3.4 1.6 0.2 setosa
> # 3个数据框按行合并,保留1个名称
> data.table::rbindlist(list2,use.names=TRUE, fill=TRUE, idcol="group")group Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1: a 5.1 3.5 1.4 0.2 setosa
2: a 4.9 3.0 1.4 0.2 setosa
3: b 5.4 3.9 1.7 0.4 setosa
4: b 4.6 3.4 1.4 0.3 setosa
5: c 5.4 3.7 1.5 0.2 setosa
6: c 4.8 3.4 1.6 0.2 setosa
> # 3个数据框按行合并,保留2个名称
> do.call(rbind, list2)Sepal.Length Sepal.Width Petal.Length Petal.Width Species
a.1 5.1 3.5 1.4 0.2 setosa
a.2 4.9 3.0 1.4 0.2 setosa
b.6 5.4 3.9 1.7 0.4 setosa
b.7 4.6 3.4 1.4 0.3 setosa
c.11 5.4 3.7 1.5 0.2 setosa
c.12 4.8 3.4 1.6 0.2 setosa
> # 3个数据框按列合并
> as.data.frame(list2)a.Sepal.Length a.Sepal.Width a.Petal.Length a.Petal.Width a.Species b.Sepal.Length
1 5.1 3.5 1.4 0.2 setosa 5.4
2 4.9 3.0 1.4 0.2 setosa 4.6b.Sepal.Width b.Petal.Length b.Petal.Width b.Species c.Sepal.Length c.Sepal.Width
1 3.9 1.7 0.4 setosa 5.4 3.7
2 3.4 1.4 0.3 setosa 4.8 3.4c.Petal.Length c.Petal.Width c.Species
1 1.5 0.2 setosa
2 1.6 0.2 setosa
(3)多列表+向量——双层列表,外层列表的元素为多个列表,内层列表的元素为向量
> ## (3)多列表+向量
> list3 <- list(
+ a = list(var1=as.numeric(iris[1,1:4])),
+ b = list(var2=as.numeric(iris[6,1:4])),
+ c = list(var3=as.numeric(iris[11,1:4]))
+ )
> list3
$a
$a$var1
[1] 5.1 3.5 1.4 0.2$b
$b$var2
[1] 5.4 3.9 1.7 0.4$c
$c$var3
[1] 5.4 3.7 1.5 0.2> # 3个向量按列合并
> as.data.frame(list3)var1 var2 var3
1 5.1 5.4 5.4
2 3.5 3.9 3.7
3 1.4 1.7 1.5
4 0.2 0.4 0.2
(4)多列表+数据框——双层列表,外层列表的元素为多个列表,内层列表的元素为数据框
> ## (4)多列表+数据框
> list4 <- list(
+ x = list(
+ var1 = iris[1:2,],
+ var2 = iris[6:7,]),
+ y = list(
+ var3 = iris[11:12,],
+ var4 = iris[16:17,])
+ )
> list4
$x
$x$var1Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa$x$var2Sepal.Length Sepal.Width Petal.Length Petal.Width Species
6 5.4 3.9 1.7 0.4 setosa
7 4.6 3.4 1.4 0.3 setosa$y
$y$var3Sepal.Length Sepal.Width Petal.Length Petal.Width Species
11 5.4 3.7 1.5 0.2 setosa
12 4.8 3.4 1.6 0.2 setosa$y$var4Sepal.Length Sepal.Width Petal.Length Petal.Width Species
16 5.7 4.4 1.5 0.4 setosa
17 5.4 3.9 1.3 0.4 setosa>
> # 4个数据框行合并
> df <- lapply(list4, bind_rows)
> bind_rows(df)Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 5.4 3.9 1.7 0.4 setosa
4 4.6 3.4 1.4 0.3 setosa
5 5.4 3.7 1.5 0.2 setosa
6 4.8 3.4 1.6 0.2 setosa
7 5.7 4.4 1.5 0.4 setosa
8 5.4 3.9 1.3 0.4 setosa
> # 4个数据框列合并
> df <- as.data.frame(list4)
> dfx.var1.Sepal.Length x.var1.Sepal.Width x.var1.Petal.Length x.var1.Petal.Width
1 5.1 3.5 1.4 0.2
2 4.9 3.0 1.4 0.2x.var1.Species x.var2.Sepal.Length x.var2.Sepal.Width x.var2.Petal.Length
1 setosa 5.4 3.9 1.7
2 setosa 4.6 3.4 1.4x.var2.Petal.Width x.var2.Species y.var3.Sepal.Length y.var3.Sepal.Width
1 0.4 setosa 5.4 3.7
2 0.3 setosa 4.8 3.4y.var3.Petal.Length y.var3.Petal.Width y.var3.Species y.var4.Sepal.Length
1 1.5 0.2 setosa 5.7
2 1.6 0.2 setosa 5.4y.var4.Sepal.Width y.var4.Petal.Length y.var4.Petal.Width y.var4.Species
1 4.4 1.5 0.4 setosa
2 3.9 1.3 0.4 setosa
> dim(df)
[1] 2 20
(5)单列表+数据框——单层列表,外层列表的元素为单个列表,内层列表的元素为数据框
第(5)种情形其实可以很容易转换为第(2)种,两个的解决方法一样。
> ## (5)单列表+数据框
> list5 <- list(
+ x = list(
+ var1 = iris[1:2,],
+ var2 = iris[6:7,],
+ var3 = iris[11:12,])
+ )
> list5
$x
$x$var1Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa$x$var2Sepal.Length Sepal.Width Petal.Length Petal.Width Species
6 5.4 3.9 1.7 0.4 setosa
7 4.6 3.4 1.4 0.3 setosa$x$var3Sepal.Length Sepal.Width Petal.Length Petal.Width Species
11 5.4 3.7 1.5 0.2 setosa
12 4.8 3.4 1.6 0.2 setosa>
> #三个数据框行合并
> dplyr::bind_rows(list5$x) Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 5.4 3.9 1.7 0.4 setosa
4 4.6 3.4 1.4 0.3 setosa
5 5.4 3.7 1.5 0.2 setosa
6 4.8 3.4 1.6 0.2 setosa
> #三个数据框列合并
> as.data.frame(list5)x.var1.Sepal.Length x.var1.Sepal.Width x.var1.Petal.Length x.var1.Petal.Width
1 5.1 3.5 1.4 0.2
2 4.9 3.0 1.4 0.2x.var1.Species x.var2.Sepal.Length x.var2.Sepal.Width x.var2.Petal.Length
1 setosa 5.4 3.9 1.7
2 setosa 4.6 3.4 1.4x.var2.Petal.Width x.var2.Species x.var3.Sepal.Length x.var3.Sepal.Width
1 0.4 setosa 5.4 3.7
2 0.3 setosa 4.8 3.4x.var3.Petal.Length x.var3.Petal.Width x.var3.Species
1 1.5 0.2 setosa
2 1.6 0.2 setosa
这部分讲起来有一些绕,大家自己运行起来跑跑看就知道怎么回事了。