r语言 - 使用reduce2和rlang对列进行变异



我正在尝试以下内容:

library(tidyverse)
library(rlang)
df <- data.frame(a = 1:2)
reduce2(list(df, df, df), letters[2:3], ~ mutate(.x, !!(.y) := 2:3))
#> Error in local_error_context(dots = dots, .index = i, mask = mask): promise already under evaluation: recursive default argument reference or earlier problems?

我确实知道许多将列转换为数据框架的方法,但我正在尝试学习rlang

期望输出:

a b c
1 1 2 2
2 2 3 3

组合purrr::reduce()rlang的方法是:

library(dplyr)
library(purrr)
reduce(letters[2:3], ~ .x %>% mutate(!!.y := 2:3), .init = df)
#   a b c
# 1 1 2 2
# 2 2 3 3

,其中的技巧是将df赋值给参数.init

我不认为reduce2是正确的函数在这里,因为你实际上没有使用任何项目和数据帧列表后的第一次迭代。传递给reduce2的函数有三个参数——第一个是被约简的对象,第二个是.x中的下一项,第三个是.y中的下一项。

这意味着如果你愿意,你仍然可以使用reduce2,通过这样做:

reduce2(.x = list(df, df, df), .y = letters[2:3], 
.f = function(A, B, C) mutate(A, {{C}} := 2:3))
#>   a b c
#> 1 1 2 2
#> 2 2 3 3

但请注意,您没有使用函数体中的第二个参数。你可以直接使用reduce:

reduce(list(df, 'b', 'c'), ~ mutate(.x, !!.y := 2:3))

我相信你知道你可以做df[letters[2:3]] <- 2:3来实现相同的输出,但我不认为这是你正在寻找的。

要使用purrrrlang,您可以使用-

library(dplyr)
library(purrr)
bind_cols(df, map_dfc(letters[2:3], ~df %>% transmute(!!.x := 2:3)))
#  a b c
#1 1 2 2
#2 2 3 3

另一种方式是-

map(letters[2:3], ~df %>% mutate(!!.x := 2:3)) %>% reduce(inner_join, by = 'a')

最新更新