我在list
中有3个tibble,我想为每个tibble添加一个具有不同值的列。我发现除了使用通常的for
循环之外,很难做到这一点(当然,for
可能是本用例中最好的解决方案,但我很好奇是否有一个聪明的解决方案(。
library(tibble)
library(dplyr)
t1 <- tibble(a=1:10, b=2:11, c=3:12)
t2 <- tibble(a=1:10, b=2:11, c=3:12)
t3 <- tibble(a=1:10, b=2:11, c=3:12)
tlist <- list(t1, t2, t3)
names <- c("A", "B", "C")
我想要实现的结果将与我们在每个tibble
上执行dplyr::mutate
以分别在names
中添加值的额外列相同;举例说明:
t1 %>% mutate(name=names[1])
t2 %>% mutate(name=names[2])
t3 %>% mutate(name=names[3])
我尝试过lapply
、sapply
和mapply
(以及它们中任意两个的一些组合(或purrr::map
,但我看不到在单个tibble上应用单个值的mutate
操作的方法(即,一对一应用/映射(。Python
有zip
,它有时会创建一对值,我们可以在apply
函数中轻松访问这些值,但我们在R
中没有这种功能。
R中的一段pusedo-ish代码(模仿Python
中的zip
(:
args <- pair(tlist, names)
add.col <- function(arg.pair) -> {
arg.pair[[1]] %>% mutate(name=arg.pair[[2]])
}
res <- args %>% lapply(add.col)
请注意,apply
函数不接受Pair
对象(stats
包中的实用程序(。
当我越来越痴迷于apply
时,我很可能会有盲点;有没有一种聪明的方法来进行这种一对一的映射?
使用map2
:
library(purrr)
library(dplyr)
map2(tlist, names,
~ .x %>%
mutate(name = .y))
或在具有Map
:的R基中
Map(function(x, y) transform(x, name = y), tlist, names)
输出:
[[1]]
# A tibble: 10 × 4
a b c name
<int> <int> <int> <chr>
1 1 2 3 A
2 2 3 4 A
3 3 4 5 A
4 4 5 6 A
5 5 6 7 A
6 6 7 8 A
7 7 8 9 A
8 8 9 10 A
9 9 10 11 A
10 10 11 12 A
[[2]]
# A tibble: 10 × 4
a b c name
<int> <int> <int> <chr>
1 1 2 3 B
2 2 3 4 B
3 3 4 5 B
4 4 5 6 B
5 5 6 7 B
6 6 7 8 B
7 7 8 9 B
8 8 9 10 B
9 9 10 11 B
10 10 11 12 B
[[3]]
# A tibble: 10 × 4
a b c name
<int> <int> <int> <chr>
1 1 2 3 C
2 2 3 4 C
3 3 4 5 C
4 4 5 6 C
5 5 6 7 C
6 6 7 8 C
7 7 8 9 C
8 8 9 10 C
9 9 10 11 C
10 10 11 12 C
mapply
也适用:
mapply(mutate, tlist, name=names, SIMPLIFY=F)
使用imap
library(purrr)
library(dplyr)
imap(setNames(tlist, names), ~ .x %>%
mutate(name = .y))