正如其他人已经指出的那样,变量名不能在mutate_at 中访问,这对于即将到来的mutate(across()) 也是如此。我将这个问题作为dplyrhere 的功能请求来解决,但显然,这种数据整理任务对于dplyr 来说太专业了。下面我针对这种数据整理问题提供了我最喜欢的解决方法,它包括两个步骤:
- 使用
!! rlang::sym() 定义自定义 mutate 函数,以根据变量名称的字符向量生成变量
- 使用
purrr::reduce 应用此自定义函数。
library(tidyverse)
# your toy data
df <- mtcars %>%
as_tibble %>%
mutate_all(list(new =~ ./4))
# step 1: generate helper function, in this case a simple `mutate` call
gen_corrected <- function(df, x) {
mutate(df,
"{x}_corrected" := !! rlang::sym(x) - !! rlang::sym(str_c(x, "_new"))
)
}
# step 2:
# use purrr's `reduce` on the vector of vars you want to change
# the vector of variables can be defined in a separate step
# important: you need to set `.init = .`
df %>%
purrr::reduce(c('carb', 'disp'), gen_corrected, .init = .)
#> # A tibble: 32 x 24
#> mpg cyl disp hp drat wt qsec vs am gear carb mpg_new
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 21 6 160 110 3.9 2.62 16.5 0 1 4 4 5.25
#> 2 21 6 160 110 3.9 2.88 17.0 0 1 4 4 5.25
#> 3 22.8 4 108 93 3.85 2.32 18.6 1 1 4 1 5.7
#> 4 21.4 6 258 110 3.08 3.22 19.4 1 0 3 1 5.35
#> 5 18.7 8 360 175 3.15 3.44 17.0 0 0 3 2 4.68
#> 6 18.1 6 225 105 2.76 3.46 20.2 1 0 3 1 4.53
#> 7 14.3 8 360 245 3.21 3.57 15.8 0 0 3 4 3.58
#> 8 24.4 4 147. 62 3.69 3.19 20 1 0 4 2 6.1
#> 9 22.8 4 141. 95 3.92 3.15 22.9 1 0 4 2 5.7
#> 10 19.2 6 168. 123 3.92 3.44 18.3 1 0 4 4 4.8
#> # … with 22 more rows, and 12 more variables: cyl_new <dbl>, disp_new <dbl>,
#> # hp_new <dbl>, drat_new <dbl>, wt_new <dbl>, qsec_new <dbl>, vs_new <dbl>,
#> # am_new <dbl>, gear_new <dbl>, carb_new <dbl>, carb_corrected <dbl>,
#> # disp_corrected <dbl>
由reprex package (v0.3.0) 于 2020 年 5 月 21 日创建
In the github issue mention above@Romain Francois 为这个问题提供了另一种解决方法。