R:将列表转换为data.frame
其中一些元素为R:将列表转换为data.frame,r,list,dataframe,R,List,Dataframe,其中一些元素为NULL,而其他元素可以具有多个子元素,例如,第三个元素具有子元素[[1]]和[[2]] 我想将这些列表元素组合成一个类似这样的data.frame(为了方便起见,我省略了Score2到Score6列的内容): 我尝试了以下操作,但出现了错误 Gender ID Class Score1 Score2 ... Score6 1 Female 1 A 21.60 2 Female 2 A 25.58 3 Male 2 A
NULL
,而其他元素可以具有多个子元素,例如,第三个元素具有子元素[[1]]
和[[2]]
我想将这些列表元素组合成一个类似这样的data.frame(为了方便起见,我省略了Score2到Score6列的内容):
我尝试了以下操作,但出现了错误
Gender ID Class Score1 Score2 ... Score6
1 Female 1 A 21.60
2 Female 2 A 25.58
3 Male 2 A 18.31
4 Female 3 A 27.16
5 Male 3 A 14.67
试试这个:
> ldply(mylist, data.frame)
Gender ID Class Score1 Score2 Score3 Score4 Score5 Score6 Gender.1 ID.1 Class.1 Score1.1 Score2.1 Score3.1 Score4.1 Score5.1 Score6.1
1 Female 1 A 21.60 39.61 8.85 13.66 2.650000 6.947368 <NA> <NA> <NA> NA NA NA NA NA NA
2 Female 2 A 25.58 55.01 1.66 3.60 15.272727 15.583333 Female 3 A 27.16 58.39 1.66 3.60 16.272727 16.583333
3 Male 2 A 18.31 36.28 2.13 4.24 8.571429 8.454545 Male 3 A 14.67 29.07 2.13 4.24 6.857143 6.818182
ll您只需使用两个tidyverse
函数即可完成此操作purrr::reduce
允许您在列表或向量中应用函数,而dplyr::bind_rows
就像一个扩展的、更智能的rbind
请注意,正如我在评论中所说,您会收到关于将字符向量与因子向量绑定的警告,但这只是一个警告,而不是错误
purrr::reduce(mylist,dplyr::bind_行)
#>绑定行中的警告(x,.id):绑定字符和因子向量,
#>强制转换为字符向量
...
#>性别ID类分数1分2分3分4分5分6
#>1女1 A 21.60 39.61 8.85 13.66 2.650000 6.947368
#>2女2 A 25.58 55.01 1.66 3.60 15.272727 15.583333
#>3男2 A 18.31 36.28 2.13 4.24 8.571429 8.4545
#>4女3 A 27.16 58.39 1.66 3.60 16.272727 16.583333
#>5男3 A 14.67 29.07 2.13 4.24 6.857143 6.818182
我提出了一个名为unlist\u的广义unlist
函数,除非
与unlist
类似,但有以下区别:
- 它有一个
谓词
参数,用于保持某些子元素不变(如果安装了purrr
,则支持公式表示法)
…
将参数传递给谓词
keep_null
用于保留(默认)或删除null
元素
与unlist
类似,它的特点是参数recursive
和use.names
具有相同的默认值。默认情况下,参数设置为TRUE
,它还具有一个keep_null
参数,我默认设置为TRUE
ll <- unlist(lapply(mylist, function(x) if(is.data.frame(x)) list(x) else x), recursive = FALSE)
do.call(rbind, ll)
Gender ID Class Score1 Score2 Score3 Score4 Score5 Score6
1 Female 1 A 21.60 39.61 8.85 13.66 2.650000 6.947368
2 Female 2 A 25.58 55.01 1.66 3.60 15.272727 15.583333
3 Male 2 A 18.31 36.28 2.13 4.24 8.571429 8.454545
4 Female 3 A 27.16 58.39 1.66 3.60 16.272727 16.583333
5 Male 3 A 14.67 29.07 2.13 4.24 6.857143 6.818182
然后就可以直接对结果调用bind\u行(dfs\u new)
或do.call(rbind,dfs\u new)
unlist_unless(dfs, is.data.frame, keep_null = FALSE)
# [[1]]
# Sepal.Length Sepal.Width Petal.Length
# 1 5.1 3.5 1.4
#
# [[2]]
# Sepal.Length Sepal.Width Petal.Length
# 2 4.9 3 1.4
#
# [[3]]
# Sepal.Length Sepal.Width Petal.Length
# 3 4.7 3.2 1.3
#
# [[4]]
# Sepal.Length Sepal.Width Petal.Length
# 4 4.6 3.1 1.5
unlist_unless(dfs, is.data.frame, recursive = FALSE)
# [[1]]
# Sepal.Length Sepal.Width Petal.Length
# 1 5.1 3.5 1.4
#
# [[2]]
# NULL
#
# [[3]]
# Sepal.Length Sepal.Width Petal.Length
# 2 4.9 3 1.4
#
# [[4]]
# Sepal.Length Sepal.Width Petal.Length
# 3 4.7 3.2 1.3
#
# [[5]]
# [[5]][[1]]
# Sepal.Length Sepal.Width Petal.Length
# 4 4.6 3.1 1.5
#
#
# [[6]]
# NULL
这些是警告,不是错误。您没有在df
中获得所需的数据帧吗?@camille,没有,我不相关:
> ldply(mylist, data.frame)
Gender ID Class Score1 Score2 Score3 Score4 Score5 Score6 Gender.1 ID.1 Class.1 Score1.1 Score2.1 Score3.1 Score4.1 Score5.1 Score6.1
1 Female 1 A 21.60 39.61 8.85 13.66 2.650000 6.947368 <NA> <NA> <NA> NA NA NA NA NA NA
2 Female 2 A 25.58 55.01 1.66 3.60 15.272727 15.583333 Female 3 A 27.16 58.39 1.66 3.60 16.272727 16.583333
3 Male 2 A 18.31 36.28 2.13 4.24 8.571429 8.454545 Male 3 A 14.67 29.07 2.13 4.24 6.857143 6.818182
ll <- unlist(lapply(mylist, function(x) if(is.data.frame(x)) list(x) else x), recursive = FALSE)
do.call(rbind, ll)
Gender ID Class Score1 Score2 Score3 Score4 Score5 Score6
1 Female 1 A 21.60 39.61 8.85 13.66 2.650000 6.947368
2 Female 2 A 25.58 55.01 1.66 3.60 15.272727 15.583333
3 Male 2 A 18.31 36.28 2.13 4.24 8.571429 8.454545
4 Female 3 A 27.16 58.39 1.66 3.60 16.272727 16.583333
5 Male 3 A 14.67 29.07 2.13 4.24 6.857143 6.818182
unlist_unless <- function(x, predicate = function(x) FALSE, ..., recursive = TRUE, use.names = TRUE, keep_null = TRUE){
if(inherits(predicate, "formula")) {
if (requireNamespace("purrr")) predicate <- purrr::as_mapper(predicate) else
stop("Package `purrr` needs to be installed to use formula notation")
}
unlist(lapply(x, function(y){
if(predicate(y, ...) || (keep_null && is.null(y)))
list(y)
else if (is.list(y) && recursive)
unlist_unless(y, predicate = predicate, ..., keep_null=keep_null, use.names = use.names)
else y}),
recursive = FALSE,
use.names = use.names)
}
df <- head(iris)[1:3]
dfs<- list(df[1,],
NULL,
list(df[2,],
df[3,],
list(df[4,]),
NULL))
unlist_unless(dfs, is.data.frame)
# [[1]]
# Sepal.Length Sepal.Width Petal.Length
# 1 5.1 3.5 1.4
#
# [[2]]
# NULL
#
# [[3]]
# Sepal.Length Sepal.Width Petal.Length
# 2 4.9 3 1.4
#
# [[4]]
# Sepal.Length Sepal.Width Petal.Length
# 3 4.7 3.2 1.3
#
# [[5]]
# Sepal.Length Sepal.Width Petal.Length
# 4 4.6 3.1 1.5
#
# [[6]]
# NULL
unlist_unless(dfs, is.data.frame, keep_null = FALSE)
# [[1]]
# Sepal.Length Sepal.Width Petal.Length
# 1 5.1 3.5 1.4
#
# [[2]]
# Sepal.Length Sepal.Width Petal.Length
# 2 4.9 3 1.4
#
# [[3]]
# Sepal.Length Sepal.Width Petal.Length
# 3 4.7 3.2 1.3
#
# [[4]]
# Sepal.Length Sepal.Width Petal.Length
# 4 4.6 3.1 1.5
unlist_unless(dfs, is.data.frame, recursive = FALSE)
# [[1]]
# Sepal.Length Sepal.Width Petal.Length
# 1 5.1 3.5 1.4
#
# [[2]]
# NULL
#
# [[3]]
# Sepal.Length Sepal.Width Petal.Length
# 2 4.9 3 1.4
#
# [[4]]
# Sepal.Length Sepal.Width Petal.Length
# 3 4.7 3.2 1.3
#
# [[5]]
# [[5]][[1]]
# Sepal.Length Sepal.Width Petal.Length
# 4 4.6 3.1 1.5
#
#
# [[6]]
# NULL
do.call(rbind,unlist_unless(dfs, is.data.frame))
# Sepal.Length Sepal.Width Petal.Length
# 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
# or
library(dplyr)
unlist_unless(dfs, is.data.frame) %>% bind_rows
# Sepal.Length Sepal.Width Petal.Length
# 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