如何用新版tidy eval的{{}}实现dplyr_join无引号by参数关联
解决方案:用新版Tidy Eval实现无引号列名的Join函数
问题出在你尝试直接在命名向量的名称部分使用{{}}——R的语法不允许在c(name = value)的name位置直接做插值。要实现无引号列名传入,需要先把捕获的符号转换成字符串,再构建by参数需要的命名向量。
正确实现代码
library(dplyr) library(rlang) data("iris") iris2 <- iris %>% select(Species) %>% filter(Species != "versicolor") %>% mutate(id = case_when(Species == "virginica" ~ 1, TRUE ~ 2)) %>% distinct() join_iris <- function(data1, data2, join_col1, join_col2) { # 用{{}}捕获符号,再转成字符串 col1_str <- as_name({{ join_col1 }}) col2_str <- as_name({{ join_col2 }}) data_out <- data1 %>% inner_join( data2, by = setNames(col2_str, col1_str) ) data_out } # 调用测试 result <- join_iris(iris, iris2, Species, Species) # 验证和期望输出一致 joined_iris <- iris %>% inner_join(iris2, by = c("Species" = "Species")) all.equal(result, joined_iris)
关键说明
{{ join_col1 }}会捕获传入的无引号列名(比如Species)为quosure对象,as_name()将其转换为字符串"Species"。setNames(col2_str, col1_str)用来构建by需要的命名向量,效果等同于c("Species" = "Species")。- 完全不需要使用已弃用的
quo_text或ensym,新版Tidy Eval的{{}}配合as_name()就能完美解决。
内容的提问来源于stack exchange,提问作者mfg3z0
相关产品推荐
相关产品推荐

