R操作中的一对一应用/映射



我在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])

我尝试过lapplysapplymapply(以及它们中任意两个的一些组合(或purrr::map,但我看不到在单个tibble上应用单个值的mutate操作的方法(即,一对一应用/映射(。Pythonzip,它有时会创建一对值,我们可以在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))

最新更新