【问题标题】:Pass argument to dplyr将参数传递给 dplyr
【发布时间】:2015-07-01 15:59:55
【问题描述】:

我想将参数传递给使用 dplyr 的函数。

这个想法是转换数据框的特定列(我的参数)的数据。

这是一个说明性示例:

example = function(x){
  df %>%
    mutate( paste0(x, '_with_noise') = x + rnorm(n(), 0, 0.01))
}

问题是我收到此错误消息:

> Error: unexpected '=' in: "  df %>%
>     mutate( paste(x, '_with_noise', sep = '') ="
> > } Error: unexpected '}' in "}"

我也尝试使用这些,但我遇到了完全相同的错误。

  • mutate_ 而不是 mutate
  • quote()

【问题讨论】:

    标签: r function arguments dplyr


    【解决方案1】:

    以下是您将如何使用mutate_

    example = function(x){
      tx <- lazyeval::interp(~z+rnorm(n(), 0, 0.01), z=as.name(x))
      tn <- paste0(x, '_with_noise')
      df %>%
        mutate_( .dots=setNames(list(tx), tn))
    }
    
    example("a")
    example("b")
    

    在 dplyr (vignette("nse","dplyr")) 的 NSE 小插图中有这样的例子。这种方法比粘贴任意字符串并评估结果更安全。

    【讨论】:

    • dplyr 的一大优势是可读性在 NSE 中完全消失了。 太可惜了!
    • @Ricol 解决特定问题几乎总是比解决一类问题更简单。 (我认为 dplyr 可以用 SE 做得更好,但我不太清楚你需要哪些组件)
    【解决方案2】:

    paste 命令在 mutate 中在这里不起作用,因此最好将变量名称分配给附加变量 y

    example = function(x){
      y <- paste(x, '_with_noise', sep = '')
      df %>%
        mutate(y = x + rnorm(n(), 0, 0.01))
    }
    

    所以如果你的数据是

    a <- c("A","B","C")
    b <- c(2,3,4)
    df <- data.frame(a,b)
    
    > df
      a b
    1 A 2
    2 B 3
    3 C 4
    

    打电话

    > example(df$b)
    

    导致结果

      a b        y
    1 A 2 2.013845
    2 B 3 2.998154
    3 C 4 3.987750
    

    【讨论】:

    • 谢谢,paste 函数不起作用,因为 x 不是字符串。如果我将 x 放在逗号之间,则 mutate 不起作用。
    • 如果你把x放在逗号之间,x就变成了一个字符串,因此你不能再对它进行算术运算,所以mutate不起作用似乎是合乎逻辑的那就不要了。
    • 你是对的。实际上这个解决方案不起作用,因为噪声变量的名称不是 y 而不是 x_with_noise。
    【解决方案3】:

    要实现这个技巧,您必须将整个命令放入 paste 函数中。 顺便说一句,最好使用paste0 而不是paste(..., sep = '')

    这是一个工作示例。

    example = function(x){
      y <- as.character(substitute(x))
      eval(parse(text = paste0(
        "df %>% mutate(", y, "_with_noise =", y, " + rnorm(n(), 0, 0.01) )"
        )))
    }
    
    set.seed(99)
    df <- as.data.frame(matrix(sample(10, 25, T), ncol = 5, 
                                dimnames = list(NULL, letters[1:5]) ))
    example(b)
    #    a  b c d e b_with_noise
    # 1  6 10 6 7 3     9.996149
    # 2  2  7 6 4 1     7.008946
    # 3  7  3 2 2 9     2.991608
    # 4 10  4 7 1 6     3.995421
    # 5  6  2 7 2 8     2.001143
    

    【讨论】:

    • 它有效,非常感谢。让我知道是否有办法使用更简单的语法
    猜你喜欢
    • 2015-03-14
    • 2017-10-16
    • 1970-01-01
    • 1970-01-01
    • 2018-01-08
    • 2017-06-06
    • 1970-01-01
    相关资源
    最近更新 更多