我在一个list中有3个tibbles,我想为每一列添加一个具有不同值的列。除了使用通常的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")我想要达到的结果与在每个dplyr::mutate上分别添加带有names值的额外列的结果相同;以举例说明:
t1 %>% mutate(name=names[1])
t2 %>% mutate(name=names[2])
t3 %>% mutate(name=names[3])我尝试过lapply、sapply和mapply (以及其中两种方法的一些组合),或者purrr::map,我看不出有一种方法可以将单一值的mutate操作应用于单个tibble (即一对一的应用/映射)。Python有zip,它有时会创建一对值,我们可以在apply函数中轻松地访问这些值,但是在R中没有这种功能。
R中的一段pusedo-ish代码(它模仿了zip在Python中的样子):
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的时候,我很可能会有盲点;有没有一种聪明的方法来进行一对一的映射?
发布于 2022-09-29 13:21:24
使用map2
library(purrr)
library(dplyr)
map2(tlist, names,
~ .x %>%
mutate(name = .y))或在基R中使用Map
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 发布于 2022-09-29 13:28:22
mapply也可以工作:
mapply(mutate, tlist, name=names, SIMPLIFY=F)发布于 2022-09-29 14:39:04
使用imap
library(purrr)
library(dplyr)
imap(setNames(tlist, names), ~ .x %>%
mutate(name = .y))https://stackoverflow.com/questions/73896188
复制相似问题