首页 文章

Dplyr - Mutate使用其他动态命名的变量动态命名变量

提问于
浏览
5

我正在尝试使用动态创建的名称创建一个新列,并使用涉及其他动态创建的变量的表达式填充该字段 . 例如,考虑以下数据框架 .

ID    multiplier    value1_2015    value2_2015    value1_2016    value2_2016
 1           0.5              2              3              1              4
 2           1.0              2              4              5              1

我想编写一个给定数据框和一年的函数,然后仅计算相应年份变量的表达式,并将结果存储在名为 total_year 的列中,其中 year 是给予函数的值 . 例如,如果表达式是

multiplier * value1_year + value2_year 我打电话给 my_fun(df, 2016) 我应该收到

ID multiplier value1_2015 value2_2015 value1_2016 value2_2016  total_2016
 1        0.5           2           3           1           4         4.5
 2        1.0           2           4           4           5           9

这就是我所拥有的

my_fun <- function(df, year) {

 year <- enquo(year)

 total_header <- paste("total", quo_name(year), sep = "_")
 calc1_header <- paste("value1", quo_name(year), sep = "_")
 calc2_header <- paste("value2", quo_name(year), sep = "_")

 calc1_header <- enquo(calc1_header)
 calc2_header <- enquo(calc2_header)

 ret_table <- df %>%
 mutate(!!total_header := multiplier * !!calc1_header + !!calc2_header)

 return(ret_table)

}

当我尝试这个时,我得到以下 Error in mutate_impl(.data, dots) : Evaluation error: non-numeric argument to binary operator.

使用类似 !!total_header := !!calc1_header 之类的内容替换表达式时没有错误,会生成正确的列名,但列中的值是字符串"value1_2016",而不是名为 value1_2016 的列中的相应值 .

1 回答

  • 5

    在这里,我们不需要 enquo/quo_name for 'year',因为我们传递的是数值 . paste 的输出将为 character class,使用 sym 来自 rlang (如提及@joran),这可以转换为符号并使用 !! 进行评估 . 确保在'!! calc1_header'和'!! calc2_header'周围添加大括号以评估特定对象

    my_fun <- function(df, year) {
    
      total_header <- paste("total", year, sep = "_")
      calc1_header <- rlang::sym(paste("value1", year, sep = "_"))
      calc2_header <- rlang::sym(paste("value2", year, sep = "_"))
    
     df %>%
           mutate(!!total_header := multiplier * (!!calc1_header) + (!!calc2_header))
    
    
    
    }
    
    my_fun(df1, 2016)
    #   ID multiplier value1_2015 value2_2015 value1_2016 value2_2016 total_2016
    #1  1        0.5           2           3           1           4        4.5
    #2  2        1.0           2           4           4           5        9.0
    

相关问题