dplyr summarise函数调用全局变量异常:自定义函数返回全0问题排查
解决dplyr函数中字符串列名参数失效的问题
这个问题本质上是dplyr的非标准评估(NSE)机制导致的——你直接传入字符串列名时,dplyr并没有把它解析为数据框里的目标列,而是把indicator当成了字面量字符串来判断,比如你传了'pass_rate',代码实际在判断"pass_rate" <= 0.8,这显然永远为FALSE,所以sum()的结果全是0。
下面给你两种实用的解决方法:
方法1:使用.data代词(推荐处理字符串参数的方式)
dplyr提供了.data代词,可以直接通过字符串索引引用数据框中的列,完美适配你的传参方式。修改后的函数如下:
thresh_measure <- function(data, indicator, thresh_value) { d1 <- data %>% group_by(class_number, outcome) %>% # 用.data[[indicator]]引用目标列 summarize(n = sum(.data[[indicator]] <= thresh_value), .groups = "drop") %>% spread(outcome, n) d1$thresh_value <- thresh_value return(d1) }
这里额外加上.groups = "drop"是为了显式取消分组,避免后续操作可能出现的分组残留问题,让代码更严谨。
方法2:使用curly-curly操作符(兼容裸列名和字符串)
如果你希望函数同时支持传入裸列名(比如pass_rate)和字符串列名(比如'pass_rate'),可以用rlang包的ensym()配合{{ }}(curly-curly)操作符:
thresh_measure <- function(data, indicator, thresh_value) { # 将输入转换为符号,同时支持裸名和字符串 indicator <- rlang::ensym(indicator) d1 <- data %>% group_by(class_number, outcome) %>% # 用{{indicator}}解析目标列 summarize(n = sum({{indicator}} <= thresh_value), .groups = "drop") %>% spread(outcome, n) d1$thresh_value <- thresh_value return(d1) }
这样你既可以调用thresh_measure(df, 'pass_rate', 0.8),也可以调用thresh_measure(df, pass_rate, 0.8),两种方式都能正常工作。
现在再运行你的测试代码final_test <- thresh_measure(df, 'pass_rate', 0.8),就能得到正确的计算结果了。
内容的提问来源于stack exchange,提问作者Chad Coleman
相关产品推荐
相关产品推荐

