You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解决R函数中mutate可选参数为NULL时的报错问题

问题描述

数据集

data <- data.frame(school_type = c("nursery", "nursery", "nursery", "nursery", "primary", "primary", "primary", "primary"), 
                   staff_type = c("manager", "manager", "teacher", "teacher", "manager", "manager", "teacher", "teacher"),
                   age_group = c("20-30","30-40","20-30","30-40","20-30","30-40","20-30","30-40"), 
                   number_staff = c(40, 10, 20, 30, 40, 10, 20, 30))

对应的表格:

school_typestaff_typeage_groupnumber_staff
nurserymanager20-3040
nurserymanager30-4010
nurseryteacher20-3020
nurseryteacher30-4030
primarymanager20-3040
primarymanager30-4010
primaryteacher20-3020
primaryteacher30-4030

自定义函数

my_function <- function(group1 = NULL, 
                        group2 = NULL,
                        nongroup = NULL){
  
data1 <- data %>%
         group_by({{group1}}, {{group2}} ) %>%
         summarise(number_staff = sum(number_staff, na.rm = T)) %>%
         mutate({{nongroup}} := "Total")
                                          
return(data1)
}

运行情况

  • 示例1:传入nongroup参数可正常运行
x <- my_function(group1 = school_type,
                 group2 = staff_type,
                 nongroup = age_group)
  • 示例2:nongroup设为NULL时报错,错误信息:

Error in quos():
! The LHS of := must be a string or a symbol
Run rlang::last_error() to see where the error occurred.

需求:让函数支持可选的nongroup参数,可根据场景选择是否添加额外列。


解决方案

核心思路是判断nongroup参数是否有效,仅当它不为空时执行添加列的操作,以下提供两种实现方式:

方法1:条件分支式实现

my_function <- function(group1 = NULL, 
                        group2 = NULL,
                        nongroup = NULL){
  
  data1 <- data %>%
    group_by({{group1}}, {{group2}} ) %>%
    summarise(number_staff = sum(number_staff, na.rm = T), .groups = "drop")
  
  # 仅当nongroup参数被传入时添加列
  if (!is.null(enexpr(nongroup))) {
    data1 <- data1 %>% mutate({{nongroup}} := "Total")
  }
  
  return(data1)
}
  • 用enexpr(nongroup)捕获参数表达式,避免直接判断NULL时的引用问题
  • 添加.groups = "drop"消除分组残留的警告

方法2:管道连贯式实现

my_function <- function(group1 = NULL, 
                        group2 = NULL,
                        nongroup = NULL){
  
  data %>%
    group_by({{group1}}, {{group2}} ) %>%
    summarise(number_staff = sum(number_staff, na.rm = T), .groups = "drop") %>%
    {
      # 条件判断决定是否执行mutate
      if (!is.null(enexpr(nongroup))) {
        mutate(., {{nongroup}} := "Total")
      } else {
        .
      }
    }
}

这种方式用大括号包裹逻辑,保持管道的连贯性,无需额外变量赋值。

验证效果

  • 不传nongroup参数的输出:
my_function(group1 = school_type, group2 = staff_type)
school_typestaff_typenumber_staff
nurserymanager50
nurseryteacher50
primarymanager50
primaryteacher50
  • 传入nongroup参数的输出:
my_function(group1 = school_type, group2 = staff_type, nongroup = age_group)
school_typestaff_typenumber_staffage_group
nurserymanager50Total
nurseryteacher50Total
primarymanager50Total
primaryteacher50Total

内容的提问来源于stack exchange,提问作者fe108

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 10:42:53