在mutate_all中的函数内部使用one_of / vars

时间:2018-07-31 22:30:27

标签: r dplyr

我需要用列之一减去数据集的所有列。我需要的列的名称是动态的,存储在数据集之外,并在下面表示为c("a")

dataset <- data.frame(a = c(0.021, 0.011, -0.031, -0.021, -0.041, 0.061), 
                      b = c(0.022, 0.012, -0.032, -0.022, -0.042, 0.062), 
                      c = c(0.010, 0.000, -0.020, 0.010, -0.030, 0.070))
dataset %>% mutate_all(funs( (. - one_of(c("a"))) ))

运行此命令时,产生的错误是Evaluation error: Variable context not set.,我知道这与在one_of()内部调用funs()有关。不太优雅的解决方案是:

dataset - dataset %>% select(one_of("a")) %>% pull

尽管如此,我很好奇为什么我不能做到前者。

3 个答案:

答案 0 :(得分:1)

您可以这样做:

dataset %>% mutate_all(`-`,.$a)
#   a      b      c
# 1 0  0.001 -0.011
# 2 0  0.001 -0.011
# 3 0 -0.001  0.011
# 4 0 -0.001  0.031
# 5 0 -0.001  0.011
# 6 0  0.001  0.009

或类似于@Miha的评论:

dataset %>% transmute_all( funs(new=. - a))
#   a_new  b_new  c_new
# 1     0  0.001 -0.011
# 2     0  0.001 -0.011
# 3     0 -0.001  0.011
# 4     0 -0.001  0.031
# 5     0 -0.001  0.011
# 6     0  0.001  0.009

我跳过new=,首先从其自身减去a,不能将其用于其他变量(感谢@aosmith)。

答案 1 :(得分:1)

为了动态选择要减去的列,您需要使用tidyeval

编写此函数的一种方法:首先用enquo为减法列创建一个等额数,然后使用它来选择要在mutate_all内减去的列。 .[[quo_name(col_quo)]]位相当于.$a的tidyeval,如果您正在使用set列,则可能会用到。

library(dplyr)

dataset <- data.frame(a = c(0.021, 0.011, -0.031, -0.021, -0.041, 0.061), 
                      b = c(0.022, 0.012, -0.032, -0.022, -0.042, 0.062), 
                      c = c(0.010, 0.000, -0.020, 0.010, -0.030, 0.070))

subtract_col <- function(data, col) {
  col_quo <- enquo(col)

  data %>%
    mutate_all(function(x) x - .[[quo_name(col_quo)]])
}

subtract_col(dataset, a)
#>   a      b      c
#> 1 0  0.001 -0.011
#> 2 0  0.001 -0.011
#> 3 0 -0.001  0.011
#> 4 0 -0.001  0.031
#> 5 0 -0.001  0.011
#> 6 0  0.001  0.009

subtract_col(dataset, c)
#>        a      b c
#> 1  0.011  0.012 0
#> 2  0.011  0.012 0
#> 3 -0.011 -0.012 0
#> 4 -0.031 -0.032 0
#> 5 -0.011 -0.012 0
#> 6 -0.009 -0.008 0

reprex package(v0.2.0)于2018-07-31创建。

答案 2 :(得分:0)

Camille的答案具有到达目标的所有条件,但是,如果您正在寻找单线的话:

dataset %>% mutate_all(funs((. - !!rlang::sym(c("a")))))