能快速将复杂的list结构扁平化成dataframe
简单的讲,do.call 的功能就是执行一个函数,而这个函数的参数呢,放在一个list里面, 是list的每个子元素。它可以在实际调用函数时将参数以列表的形式传入,下面是一个简单的例子:
> tmp <- data.frame('letter' = letters[1:10], 'number' = 1:10, 'value' = c('+','-'))
> tmp
letter number value
1 a 1 +
2 b 2 -
3 c 3 +
4 d 4 -
5 e 5 +
6 f 6 -
7 g 7 +
8 h 8 -
9 i 9 +
10 j 10 -
> tmp[[1]]
[1] a b c d e f g h i j
> tmp[[2]]
[1] 1 2 3 4 5 6 7 8 9 10
> tmp[[3]]
[1] + - + - + - + - + -
> do.call("paste", c(tmp, sep = ""))
[1] "a1+" "b2-" "c3+" "d4-" "e5+" "f6-" "g7+" "h8-" "i9+" "j10-"
## 调用函数时将参数以列表的形式传入
通过do.call(),实现多个数据框的合并。
tidyverse中
> list1
[[1]]
up down number
1 A a 1
2 B b 2
3 C c 3
4 D d 4
5 E e 5
[[2]]
up down number
1 A a 1
2 B b 2
3 C c 3
4 D d 4
5 E e 5
[[3]]
up down number
1 A a 1
2 B b 2
3 C c 3
4 D d 4
5 E e 5
> do.call("rbind",list1)
up down number
1 A a 1
2 B b 2
3 C c 3
4 D d 4
5 E e 5
6 A a 1
7 B b 2
8 C c 3
9 D d 4
10 E e 5
11 A a 1
12 B b 2
13 C c 3
14 D d 4
15 E e 5
通过 do.call() 实现了内部函数对外部输入的自动匹配。
#构建求和参数
Sum <- function(a = 1, b = 2, c = 3, d = 4) {
message("a:", a, " b:", b, " c:", c, " d:", d)
return(sum(a, b, c, d))
}
Args <- expand.grid(
c(1, 2),
c(3, 4, 5),
c(6, 7, 8, 9)
)
colnames(Args) <- c("a", "b", "c")
batchSum <- function(ArgsMat) {
args <- list()
for (i in 1:nrow(ArgsMat)) {
args_update <- c(args, ArgsMat[i, , drop = FALSE])
do.call(Sum, args = args_update)
}
}
batchSum(Args)
#> a:1 b:3 c:6 d:4
#> a:2 b:3 c:6 d:4
#> a:1 b:4 c:6 d:4
#> a:2 b:4 c:6 d:4
#> a:1 b:5 c:6 d:4
#> a:2 b:5 c:6 d:4
#> a:1 b:3 c:7 d:4
#> a:2 b:3 c:7 d:4
#> a:1 b:4 c:7 d:4
#> a:2 b:4 c:7 d:4
#> a:1 b:5 c:7 d:4
#> a:2 b:5 c:7 d:4
#> a:1 b:3 c:8 d:4
#> a:2 b:3 c:8 d:4
#> a:1 b:4 c:8 d:4
#> a:2 b:4 c:8 d:4
#> a:1 b:5 c:8 d:4
#> a:2 b:5 c:8 d:4
#> a:1 b:3 c:9 d:4
#> a:2 b:3 c:9 d:4
#> a:1 b:4 c:9 d:4
#> a:2 b:4 c:9 d:4
#> a:1 b:5 c:9 d:4
#> a:2 b:5 c:9 d:4
colnames(Args) <- c("a", "c", "d")
batchSum(Args)
#> a:1 b:2 c:3 d:6
#> a:2 b:2 c:3 d:6
#> a:1 b:2 c:4 d:6
#> a:2 b:2 c:4 d:6
#> a:1 b:2 c:5 d:6
#> a:2 b:2 c:5 d:6
#> a:1 b:2 c:3 d:7
#> a:2 b:2 c:3 d:7
#> a:1 b:2 c:4 d:7
#> a:2 b:2 c:4 d:7
#> a:1 b:2 c:5 d:7
#> a:2 b:2 c:5 d:7
#> a:1 b:2 c:3 d:8
#> a:2 b:2 c:3 d:8
#> a:1 b:2 c:4 d:8
#> a:2 b:2 c:4 d:8
#> a:1 b:2 c:5 d:8
#> a:2 b:2 c:5 d:8
#> a:1 b:2 c:3 d:9
#> a:2 b:2 c:3 d:9
#> a:1 b:2 c:4 d:9
#> a:2 b:2 c:4 d:9
#> a:1 b:2 c:5 d:9
#> a:2 b:2 c:5 d:9
##此时B是不会变的