如何在dplyr的mutate/summarize中使用固定列名编写函数?
在dplyr的mutate/summarize中使用固定列名编写自定义函数的解决方法
问题背景
需要编写一个可在dplyr的mutate()或summarize()中计算新变量的函数,其中某一列是固定列(不作为函数参数传入),但运行时出现object 'l' not found的错误,无法正确识别固定列。
可复现代码
library(tidyverse) df <- data.frame( x = rep(c("A", "B"), times = 10), y = rnorm(20), l = rep(c(TRUE, FALSE), each = 10) ) foo <- function(y) { total <- n() # total count n <- sum(l) # count of TRUE pct <- round(100 * n / total, 1) # percent of TRUE pct } df %>% group_by(x) %>% summarize( n = n(), result = foo(y = y) )
解决方法
方法1:使用.data代词(推荐)
.data是tidyverse提供的特殊代词,用于明确引用当前操作的数据框中的列,确保函数在dplyr上下文里能正确找到固定列:
foo <- function(y) { total <- n() n <- sum(.data$l) pct <- round(100 * n / total, 1) pct }
方法2:将固定列设为参数并绑定默认值
把固定列作为函数参数,用{{}}(大括号)在默认值中绑定数据框的列,调用时无需额外传参:
foo <- function(y, l = {{l}}) { total <- n() n <- sum(l) pct <- round(100 * n / total, 1) pct }
方法3:使用cur_data()获取当前数据集
cur_data()会返回当前分组的数据集(不含分组列),通过它可以直接提取固定列,适合多固定列的场景:
foo <- function(y) { total <- n() current_data <- cur_data() n <- sum(current_data$l) pct <- round(100 * n / total, 1) pct }
验证结果
修改函数后,运行原summarize代码即可得到正确结果,不会再出现找不到列的错误。
内容的提问来源于stack exchange,提问作者joshwondra
相关产品推荐
相关产品推荐

