【问题标题】:Passing a string to an R function and using it as a column name within the function将字符串传递给 R 函数并将其用作函数中的列名
【发布时间】:2020-05-25 07:04:52
【问题描述】:

我有一个数据框,其中包含几个科目的学生分数列表(每个科目由一列表示)我想为每个科目(数学、科学和阅读)进行下面的计算

avgdata_math <- data%>% 
   group_by(country) %>% 
   summarise(ci = list(bootstrap_ci(sex, Math, weight))) %>% 
   unnest_wider(ci) %>% 
   ungroup() %>% 
   mutate(country = fct_reorder(country, avg))

由于我必须重复两次相同的代码,我想编写一个函数来进行计算(不旋转数据框)

aus_nz <- function(df, subject = "Math") {
   df %>%
    group_by(country) %>% 
    summarise(ci = list(bootstrap_ci(sex, subject, weight))) %>% 
    unnest_wider(ci) %>% 
    ungroup() %>% 
    mutate(country = fct_reorder(country, avg))
}

这给了我一个错误,因为我已将列名称(主题)作为字符串传递,然后将数据分组,然后在调用 bootstrap_ci 函数时使用字符串值,而它应该是传递到那里的一列数据(应该是在分组操作之后)。

【问题讨论】:

    标签: r function dplyr tidyeval


    【解决方案1】:

    在你的函数中使用!! rlang::ensym(subject) 应该可以工作。

    aus_nz <- function(df, subject = "Math") {
       df %>%
        group_by(country) %>% 
        summarise(ci = list(bootstrap_ci(sex, !! rlang::ensym(subject), weight))) %>% 
        unnest_wider(ci) %>% 
        ungroup() %>% 
        mutate(country = fct_reorder(country, avg))
    }
    

    更新

    如果您还想将分组变量作为字符串传递给函数,并且有时您想要分组的变量不止一个,那么使用!!!rlang::ensyms() 和省略号... 参数将做这个把戏,如果它不是你函数的最后一行。 fct_reorder 只需要 one 变量。如果有两个分组变量:你会怎么做?创建两个新变量并按avg 对每个分组变量重新排序?查看您的数据也会很有帮助(可能是dput(head(...)))。

    aus_nz <- function(df, subject = "Math", ...) {
    
    group_var <- rlang::ensyms(...)
    
      df %>%
        group_by(!!! group_var) %>%
        summarise(ci = list(bootstrap_ci(sex, !! rlang::ensym(subject), weight))) %>%
        unnest_wider(ci) %>%
        ungroup() # %>% last line needs to be fixed
        # mutate(grouped_by = fct_reorder(!!! group_var, avg))
    } 
    

    如果您不想使用省略号参数,可以使用rlang::syms 和字符向量(具有一个或多个元素)来代替:

    aus_nz <- function(df, subject = "Math", group = "country") {
    
    group_var <- rlang::syms(group)
    
      df %>%
        group_by(!!! group_var) %>%
        summarise(ci = list(bootstrap_ci(sex, !! rlang::ensym(subject), weight))) %>%
        unnest_wider(ci) %>%
        ungroup() # %>% last line needs to be fixed
        # mutate(grouped_by = fct_reorder(!!! group_var, avg))
    } 
    

    【讨论】:

    • 我使用了您的方法并设法解决了我最初的问题。但是,现在我也尝试将分组变量作为参数传递。 aus_nz % group_by(!! rlang::ensym(group)) %>% summarise(ci = list(bootstrap_ci(sex, ! !rlang::ensym(subject), weight))) %>% unnest_wider(ci) %>% ungroup() %>% mutate(grouped_by = fct_reorder(!! rlang::ensym(group), avg)) }
    • 但是我也想在少数情况下按多列分组。在那种情况下,我想重用上述功能。但不知道该怎么做?我尝试将分组变量列表作为列表 c("var1", "var2") 传递,但这似乎不起作用。
    • 我更新了我的答案,但是你的最后一行需要调整。
    猜你喜欢
    • 2021-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多