mylist <- list(NULL, structure(list(Gender = structure(1L, .Label = "Female", class = "factor"),
ID = structure(1L, .Label = "1", class = "factor"), Class = structure(1L, .Label = "A", class = "factor"),
Score1 = 21.6, Score2 = 39.61, Score3 = 8.85,
Score4 = 13.66, Score5 = 2.64999999999999, Score6 = 6.94736842105265), .Names = c("Gender",
"ID", "Class", "Score1", "Score2", "Score3",
"Score4", "Score5", "Score6"), row.names = c(NA, -1L
), class = "data.frame"), list(structure(list(Gender = structure(1:2, .Label = c("Female",
"Male"), class = "factor"), ID = structure(c(1L, 1L), .Label = "2", class = "factor"),
Class = structure(c(1L, 1L), .Label = "A", class = "factor"),
Score1 = c(25.58, 18.31), Score2 = c(55.01,
36.28), Score3 = c(1.66, 2.13), Score4 = c(3.6,
4.24), Score5 = c(15.2727272727273, 8.57142857142858), Score6 = c(15.5833333333334,
8.4545454545455)), .Names = c("Gender", "ID", "Class",
"Score1", "Score2", "Score3", "Score4",
"Score5", "Score6"), row.names = c(NA, -2L), class = "data.frame"),
structure(list(Gender = structure(1:2, .Label = c("Female",
"Male"), class = "factor"), ID = structure(c(1L, 1L), .Label = "3", class = "factor"),
Class = structure(c(1L, 1L), .Label = "A", class = "factor"),
Score1 = c(27.16, 14.67), Score2 = c(58.39,
29.07), Score3 = c(1.66, 2.13), Score4 = c(3.6,
4.24), Score5 = c(16.2727272727273, 6.85714285714286),
Score6 = c(16.5833333333333, 6.81818181818185)), .Names = c("Gender",
"ID", "Class", "Score1", "Score2",
"Score3", "Score4", "Score5", "Score6"), row.names = c(NA,-2L), class = "data.frame")))
我有一个类似的列表:
> mylist
[[1]]
NULL
[[2]]
Gender ID Class Score1 Score2 Score3 Score4 Score5 Score6
1 Female 1 A 21.6 39.61 8.85 13.66 2.65 6.947368
[[3]]
[[3]][[1]]
Gender ID Class Score1 Score2 Score3 Score4 Score5 Score6
1 Female 2 A 25.58 55.01 1.66 3.60 15.272727 15.583333
2 Male 2 A 18.31 36.28 2.13 4.24 8.571429 8.454545
[[3]][[2]]
Gender ID Class Score1 Score2 Score3 Score4 Score5 Score6
1 Female 3 A 27.16 58.39 1.66 3.60 16.272727 16.583333
2 Male 3 A 14.67 29.07 2.13 4.24 6.857143 6.818182
其中一些元素是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
我尝试过以下但却出错了
> tab <- unlist(mylist, recursive = FALSE)
> df <- do.call("rbind", tab)
Warning in `[<-.factor`(`*tmp*`, ri, value = 1L) :
invalid factor level, NA generated
Warning in `[<-.factor`(`*tmp*`, ri, value = 1L) :
invalid factor level, NA generated
...
使用ldply
无法正确处理最后一个元素
> 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
答案 0 :(得分:5)
您可以使用几个tidyverse
函数非常简单地执行此操作。 purrr::reduce
允许您在列表或向量中应用函数,dplyr::bind_rows
就像一个扩展的,更智能的rbind
。
请注意,就像我在评论中所说的那样,您会收到有关您使用因子向量绑定字符向量这一事实的警告,但这只是警告,而不是错误
purrr::reduce(mylist, dplyr::bind_rows)
#> Warning in bind_rows_(x, .id): binding character and factor vector,
#> coercing into character vector
...
#> 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
答案 1 :(得分:2)
试试这个:
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
答案 2 :(得分:1)
我建议使用名为unlist
的广义unlist_unless
函数,其作用类似unlist
,但有以下区别:
predicate
参数,用于保持一些子元素不变(如果安装了purrr
,则支持公式表示法)...
将参数传递给predicate
keep_null
用于保留(默认)或删除NULL
元素与unlist
类似,它的参数recursive
和use.names
的默认设置默认设置为TRUE
,默认情况下默认设置为keep_null
,它还包含TRUE
参数默认设置为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
例子1:最简单
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
examples2:keep_null = FALSE
bind_rows(dfs_new)
然后可以直接在结果上调用do.call(rbind, dfs_new)
或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
。
[System.Data.DataColumn[]]$myitems = ([System.Data.DataColumn]("col1"),
[System.Data.DataColumn]("col2"), [System.Data.DataColumn]("col3"))