因为您要操作列名,所以需要使用 mutate_at
而不是使用列内的值的 mutate_if
tb %>% mutate_at(vars(starts_with("y")), funs(. - z))
为了创建新列,而不是覆盖现有列,我们可以给funs
命名。
tb %>% mutate_at(vars(starts_with("y")), funs(mod = . - z))
tb %>%
mutate_at(vars(starts_with("y")), funs(mod = . - z)) %>%
rename_at(vars(ends_with("_mod")), funs(paste("mod", gsub("_mod", "", .), sep = "_")))
编辑: 在 dplyr 0.8.0
或更高版本中,funs()
将被弃用 (source1 & source2),需要使用 list()
替代。
tb %>% mutate_at(vars(starts_with("y")), list(~ . - z))
tb %>% mutate_at(vars(starts_with("y")), list(mod = ~ . - z))
tb %>%
mutate_at(vars(starts_with("y")), list(mod = ~ . - z)) %>%
rename_at(vars(ends_with("_mod")), list(~ paste("mod", gsub("_mod", "", .), sep = "_")))
编辑2: dplyr
1.0.0+具有across()
函数,这进一步简化了此任务
基本用法
across()
有两个主要参数:
- 第一个参数
.cols
选择您要操作的列。它使用整洁的选择(如select()
),因此您可以按位置、名称和类型选择变量。
- 第二个参数
.fns
是要应用于每列的函数或函数列表。这也可以是purrr样式的公式(或公式列表),如~ .x / 2
。(此参数是可选的,并且如果您只想获取底层数据,则可以省略它;您将在vignette("rowwise")
中看到该技术的应用)
tb %>%
mutate(
across(starts_with("y"), ~ .x - z, .names = "mod_{col}")
)
tb %>%
mutate(
across(num_range(prefix = "y", range = 1:3), ~ .x - z, .names = "mod_{col}")
)
tb %>%
mutate(
across(c(matches("x"), contains("z")), ~ max(.x, na.rm = TRUE), .names = "max_{col}"),
across(c(y1:y3), ~ .x - z, .names = "mod_{col}")
)
2018-10-29创建,使用reprex包 (v0.2.1)