dplyr自定义函数中,如何在:=右侧引用左侧注入的变量名
解决dplyr自定义函数中引用内部生成变量的问题
在自定义函数里用:=动态生成变量名后,后续mutate()里直接引用这些变量会失败,核心原因是dplyr的求值环境无法直接识别动态生成的变量名。下面给你两种可行的解决办法,结合示例代码说明:
方法1:用sym()转符号 + !!强制求值
先把动态生成的变量名存成字符串,再转换成dplyr能识别的符号,最后用!!强制求值:
my_summary <- function(data, group_var, numsuffix) { # 提前构建变量名字符串 n_col <- paste0("n_", numsuffix) prop_col <- paste0("prop_", numsuffix) data %>% group_by({{group_var}}) %>% summarise( !!n_col := n(), # 生成计数变量 .groups = "drop" ) %>% mutate( !!prop_col := !!sym(n_col) / sum(!!sym(n_col)) # 引用动态生成的计数变量 ) }
方法2:用.data代词配合字符串索引
.data代词可以通过字符串直接访问数据框里的变量,适合这种动态变量名的场景:
my_summary <- function(data, group_var, numsuffix) { n_col <- paste0("n_", numsuffix) prop_col <- paste0("prop_", numsuffix) data %>% group_by({{group_var}}) %>% summarise( !!n_col := n(), .groups = "drop" ) %>% mutate( !!prop_col := .data[[n_col]] / sum(.data[[n_col]]) ) }
测试示例
用你提到的示例数据测试:
# 模拟dcdata和pgdata dcdata <- tibble( category = sample(c("A", "B", "C"), 100, replace = TRUE), value = rnorm(100) ) pgdata <- tibble( group = sample(c("X", "Y"), 50, replace = TRUE), score = rpois(50, lambda = 3) ) # 运行函数 my_summary(dcdata, category, "total") my_summary(pgdata, group, "count")
为什么之前的方法不行?
{{}}是用来捕获你传入函数的参数表达式(比如group_var),不是用来引用函数内部生成的变量名,直接写n_{{numsuffix}}会被当成字面量,找不到对应的变量。- 之前用
.data[[]]失败,大概率是没把变量名先存成字符串,直接写.data[["n_{{numsuffix}}"]]的话,{{}}在字符串里不会被解析,相当于找一个叫n_{{numsuffix}}的变量,自然报错。
内容的提问来源于stack exchange,提问作者Jane Lu
相关产品推荐
相关产品推荐

