【问题标题】:R functions: use argument as name within the functionR函数:在函数中使用参数作为名称
【发布时间】:2021-02-17 19:44:09
【问题描述】:

我在 R 中创建了一个用户函数,将两列相乘以创建第三列(在一个系列中),因此该函数创建了 4 个新列。

create_mult_var <- function(.data){
  .data <-.data%>%
    mutate(Q4_1_4 = Q4_1_2_TEXT*Q4_1_3_TEXT) %>% 
    mutate(Q4_2_4 = Q4_2_2_TEXT*Q4_2_3_TEXT) %>%
    mutate(Q4_3_4 = Q4_3_2_TEXT*Q4_3_3_TEXT) %>%
    mutate(Q4_4_4 = Q4_4_2_TEXT*Q4_4_3_TEXT)
  .data

我正在尝试修改此函数,以便可以将其应用于匹配相同类型的不同列集。例如,如果我想在以“Q8”开头的一系列列上重复此操作,我知道我可以执行以下操作:

create_mult_var_2 <- function(.data){
  .data <-.data%>%
    mutate(Q8_1_4 = Q8_1_2_TEXT*Q8_1_3_TEXT) %>% 
    mutate(Q8_2_4 = Q8_2_2_TEXT*Q8_2_3_TEXT) %>%
    mutate(Q8_3_4 = Q8_3_2_TEXT*Q8_3_3_TEXT) %>%
    mutate(Q8_4_4 = Q8_4_2_TEXT*Q8_4_3_TEXT)
  .data
  
}

我不想为每个 Q4 和 Q8 系列创建不同的函数,而是添加“Q4”或“Q8”作为参数。我在下面尝试了这个,但 R 不会以这种方式接受这个作为论点。有没有办法达到我想要的结果?

这不起作用:

create_mult_var <- function(.data,question){
   .data <-.data%>%
   mutate(question_1_4 = question_1_2_TEXT*question_1_3_TEXT) %>% 
   mutate(question_2_4 = question_2_2_TEXT*question_2_3_TEXT) %>%
   mutate(question_3_4 = question_3_2_TEXT*question_3_3_TEXT) %>%
   mutate(question_4_4 = question_4_2_TEXT*question_4_3_TEXT)
  .data
   
}

我想修改功能,比如我可以使用如下:

data_in %>% create_mult_var("Q4") %>% create_mult_var("Q8") 

或者类似的东西来创建这些新列?任何建议表示赞赏!谢谢!如果这是一个坏主意,对我应该如何处理有什么建议吗?

【问题讨论】:

    标签: r function dplyr


    【解决方案1】:

    我们可以使用paste 并使用!! 进行评估

    create_mult_var_2 <- function(.data, pat){
      .data <-.data%>%
        mutate(!! str_c(pat, '_1_4') :=
        !! rlang::sym(str_c(pat, '_1_2_TEXT')) *
        !! rlang::sym(str_c(pat, '_1_3_TEXT')))
      .data 
     }
    
    create_mult_var_2(data_in, "Q4")
    #  Q4_1_2_TEXT Q4_1_3_TEXT Q4_1_4
    #1           1           5      5
    #2           2           6     12
    #3           3           7     21
    #4           4           8     32
    

    此外,根据显示的模式,这也可以自动化

    library(dplyr)
    library(stringr)
    create_mult_var_3 <- function(.data, pat) {
      .data %>%
        mutate(across(matches(str_c("^", pat, "_\\d+_2")), ~
                   .* get(str_replace(cur_column(), '_2_TEXT', '_3_TEXT')),
             .names =  '{.col}_new')) %>%
        rename_at(vars(ends_with('_new')),
            ~ str_replace(., '\\d+_TEXT_new', '4'))
    
    
    
    }
    

    -测试

    create_mult_var_3(data_in, "Q4")
    #  Q4_1_2_TEXT Q4_1_3_TEXT Q4_1_4
    #1           1           5      5
    #2           2           6     12
    #3           3           7     21
    #4           4           8     32  
            
    

    数据

    data_in <- data.frame(Q4_1_2_TEXT = 1:4, Q4_1_3_TEXT = 5:8)
    

    【讨论】:

    • 谢谢!这很容易创建一个变量(Q4_1_4),我需要为每个问题类型(Q4_2_4、Q4_3_4 和 Q4_4_4)创建 4 个变量,Q4。我修改了您的答案以创建所有四个,但出现错误:
    • @NewBee 错误是什么?我只展示了一个,因为它更容易复制/粘贴和创建更多
    • !!rlang::sym(str_c(pat, : 找不到函数":="
    • @NewBee 你能出示你的packageVersion('dplyr')
    • @NewBee 可以试试create_mult_var_3这个函数吗