将两个列表合并到 R 中的数据框中
Combine two lists in a dataframe in R
我有两个结构不同的列表:
listA <- list(c("a","b","c"), c("d","e"))
listB <- list(0.05, 0.5)
listA
[[1]]
[1] "a" "b" "c"
[[2]]
[1] "d" "e"
listB
[[1]]
[1] 0.05
[[2]]
[1] 0.5
我知道如何使用循环将两个列表合并到一个如下所示的数据框中,但我确信有一种更有效的方法可以做到这一点。
data.frame(A = c("a","b","c","d","e"), B = c(rep(0.05,3), rep(0.5,2)))
A B
1 a 0.05
2 b 0.05
3 c 0.05
4 d 0.50
5 e 0.50
也许有一种更优雅的方法可以保留 list2
元素的 class numeric
...但是这个方法同样有效
df <- do.call(rbind,mapply(cbind, listA, listB))
df <- as.data.frame(df, stringsAsFactors = FALSE)
df[,2] <- as.numeric(df[,2])
EDIT Matthew Plourde 使用 Map
又名 mapply(data.frame, A=listA, B=listB, SIMPLIFY = FALSE)
的解决方案更好
这是另一种方式:
do.call(rbind,
lapply(1:length(listA),
function(i)
data.frame(A=unlist(listA[i]),
B=unlist(listB[i]))))
我更喜欢这个:
do.call(rbind,
Map(function(...) setNames(cbind.data.frame(...),
c("A", "B")),
listA, listB))
# A B
#1 a 0.05
#2 b 0.05
#3 c 0.05
#4 d 0.50
#5 e 0.50
这是另一个选项:
do.call(rbind, Map(data.frame, A=listA, B=listB))
# A B
# 1 a 0.05
# 2 b 0.05
# 3 c 0.05
# 4 d 0.50
# 5 e 0.50
如果正在寻找 tidyverse
解决方案,这里是已接受答案的模拟。使用 map
函数族的 dfr
后缀可以实现一个非常简单的解决方案,它也应该比 do.call("rbind")
.
更快
library(tidyverse)
listA <- list(c("a","b","c"), c("d","e"))
listB <- list(0.05, 0.5)
map2_dfr(listA, listB, ~ tibble(A = .x, B = .y))
#> # A tibble: 5 x 2
#> A B
#> <chr> <dbl>
#> 1 a 0.05
#> 2 b 0.05
#> 3 c 0.05
#> 4 d 0.5
#> 5 e 0.5
由 reprex package (v0.2.1)
创建于 2019-02-12
不使用do.call的另一种方式:
cbind(data.frame(listA), data.frame(listB))
这将放置索引并适当地重命名列:
df <- do.call(rbind.data.frame, Map('c', listA, listB))
colnames(df)[1] <- "A"
colnames(df)[2] <- "B"
我有两个结构不同的列表:
listA <- list(c("a","b","c"), c("d","e"))
listB <- list(0.05, 0.5)
listA
[[1]]
[1] "a" "b" "c"
[[2]]
[1] "d" "e"
listB
[[1]]
[1] 0.05
[[2]]
[1] 0.5
我知道如何使用循环将两个列表合并到一个如下所示的数据框中,但我确信有一种更有效的方法可以做到这一点。
data.frame(A = c("a","b","c","d","e"), B = c(rep(0.05,3), rep(0.5,2)))
A B
1 a 0.05
2 b 0.05
3 c 0.05
4 d 0.50
5 e 0.50
也许有一种更优雅的方法可以保留 list2
元素的 class numeric
...但是这个方法同样有效
df <- do.call(rbind,mapply(cbind, listA, listB))
df <- as.data.frame(df, stringsAsFactors = FALSE)
df[,2] <- as.numeric(df[,2])
EDIT Matthew Plourde 使用 Map
又名 mapply(data.frame, A=listA, B=listB, SIMPLIFY = FALSE)
这是另一种方式:
do.call(rbind,
lapply(1:length(listA),
function(i)
data.frame(A=unlist(listA[i]),
B=unlist(listB[i]))))
我更喜欢这个:
do.call(rbind,
Map(function(...) setNames(cbind.data.frame(...),
c("A", "B")),
listA, listB))
# A B
#1 a 0.05
#2 b 0.05
#3 c 0.05
#4 d 0.50
#5 e 0.50
这是另一个选项:
do.call(rbind, Map(data.frame, A=listA, B=listB))
# A B
# 1 a 0.05
# 2 b 0.05
# 3 c 0.05
# 4 d 0.50
# 5 e 0.50
如果正在寻找 tidyverse
解决方案,这里是已接受答案的模拟。使用 map
函数族的 dfr
后缀可以实现一个非常简单的解决方案,它也应该比 do.call("rbind")
.
library(tidyverse)
listA <- list(c("a","b","c"), c("d","e"))
listB <- list(0.05, 0.5)
map2_dfr(listA, listB, ~ tibble(A = .x, B = .y))
#> # A tibble: 5 x 2
#> A B
#> <chr> <dbl>
#> 1 a 0.05
#> 2 b 0.05
#> 3 c 0.05
#> 4 d 0.5
#> 5 e 0.5
由 reprex package (v0.2.1)
创建于 2019-02-12不使用do.call的另一种方式:
cbind(data.frame(listA), data.frame(listB))
这将放置索引并适当地重命名列:
df <- do.call(rbind.data.frame, Map('c', listA, listB))
colnames(df)[1] <- "A"
colnames(df)[2] <- "B"