【问题标题】:Is there a way to specify a column name as an argument?有没有办法将列名指定为参数?
【发布时间】:2020-04-14 18:46:13
【问题描述】:

假设我想创建一个复制所选列的函数,作为示例。

testdata <- data.frame(
  "diff1" = c(seq(1:10)),
  "diff2" = c(seq(21:30))
)

goal <- testdata %>%
  mutate(newdiff1 = diff1)

所以我创建了一个函数

funtest <- function(dat,var,newvar){
  dat %>%
    mutate(newvar = var)
}

然而,

test2 <- funtest(testdata,diff1,newdiff1)

会返回错误:

 Error: object 'diff1' not found 

这种格式有效

nondesiredformat <- funtest(testdata,testdata$diff1,newdiff1)

但这会导致新变量总是被称为“newvar”,而不是我们的第三个参数。

有没有办法改变函数,使 test2 中的参数可以工作?

谢谢

【问题讨论】:

    标签: r function arguments


    【解决方案1】:

    在函数中,我们可以使用{{}} 进行评估,即!! + enquo 用于传递给函数的不带引号的变量名,对于赋值,使用:= 而不是=

    funtest <- function(dat,var,newvar){
       dat %>%
         mutate({{newvar}} := {{var}})
            }
    funtest(testdata, diff1, newdiff1)
    #    diff1 diff2 newdiff1
    #1      1     1        1
    #2      2     2        2
    #3      3     3        3
    #4      4     4        4
    #5      5     5        5
    #6      6     6        6
    #7      7     7        7
    #8      8     8        8
    #9      9     9        9
    #10    10    10       10
    

    【讨论】:

      【解决方案2】:

      您可以为此使用 bquote:

      eval(bquote(
        dat %>% 
          mutate(.(newvar) := .(var))
      ))
      

      你也可以在你的特殊情况下更新老学校

      dat[[newvar]] = dat[[var]]
      

      【讨论】:

        【解决方案3】:

        如果您开始使用带参数的变量名编写函数,您可能会发现data.tabledplyr 更方便。我最近写了一个post on the subject。在我看来,data.tabledplyr 更容易处理标准评估。

        使用data.table,您有多种方法可以使用列名作为参数

        使用获取

        您可以使用get 将名称映射到特定范围内的值。这里的范围是你的data.table

        library(data.table)
        funtest <- function(dat,var,newvar){
          dat[, (newvar) := get(var)]
        }
        

        := 是一个按引用更新的运算符。如果您想了解更多信息,data.tablevignettes 是一个不错的起点。调用函数:

        dt = data.table(iris)
        
        funtest(dt, "Species","x")[]
             Sepal.Length Sepal.Width Petal.Length Petal.Width   Species         x
          1:          5.1         3.5          1.4         0.2    setosa    setosa
          2:          4.9         3.0          1.4         0.2    setosa    setosa
          3:          4.7         3.2          1.3         0.2    setosa    setosa
          4:          4.6         3.1          1.5         0.2    setosa    setosa
          5:          5.0         3.6          1.4         0.2    setosa    setosa
         ---                                                                      
        146:          6.7         3.0          5.2         2.3 virginica virginica
        147:          6.3         2.5          5.0         1.9 virginica virginica
        148:          6.5         3.0          5.2         2.0 virginica virginica
        149:          6.2         3.4          5.4         2.3 virginica virginica
        150:          5.9         3.0          5.1         1.8 virginica virginica
        

        使用 .SD

        您也可以使用.SD,表示数据子集。当您引用多个变量时,这会更方便。它避免了dplyr 所需的!!!rlang::sym

        您会发现自己使用非常简洁的语法进行复杂的计算:

        df[, newcolnames := lapply(.SD, mean), by = grouping_var, .SDcols = xvars]
        

        【讨论】:

          猜你喜欢
          • 2013-06-06
          • 2021-12-27
          • 1970-01-01
          • 1970-01-01
          • 2015-02-15
          • 1970-01-01
          • 1970-01-01
          • 2020-02-26
          • 1970-01-01
          相关资源
          最近更新 更多