双大括号(curly-curly braces)问题:为何函数不接受未引号变量
解决R语言双大括号(curly-curly)传入裸变量失败的问题
问题根源
你遇到的核心问题是双大括号捕获的对象类型差异:
- 当传入带引号的
"var_1"时,{{col}}拿到的是字符串,substr()能直接处理; - 当传入裸变量
var_1时,{{col}}捕获的是一个符号(symbol)对象,而substr()不支持处理符号类型,所以第一步就触发了报错。
修复方案
需要先把捕获的符号转换成字符串,推荐用rlang::as_name()(tidyverse生态下的工具)来完成转换,后续字符串相关操作都基于这个转换后的变量名。修改后的完整代码如下:
library(tidyverse) dat <- structure(list(id = 1:6, var_1 = c("1,1,-11000", "1,1,1", "0,0,0", "1,1,0", "1,1,1", "1,1,1"), var_2 = c("0,0,-13000", "0,0,0", "-13000,-13000,-13000", "6,4,-13000", "0,0,0", "0,0,0"), var_3 = c("24,7,-13000", "0,0,0", "-13000,-13000,-13000", "0,0,-13000", "0,0,0", "0,0,0")), row.names = 1:6, class = "data.frame") split_to_long <- function(col){ # 将捕获的裸变量名转换为字符串 col_name <- rlang::as_name({{col}}) i <- substr(col_name, 5, 5) temp <- dat |> select("id", {{col}}) |> separate_wider_delim({{col}}, ",", too_few = "align_start", names = c(paste0(col_name,"_1"), paste0(col_name,"_2"), paste0(col_name,"_3"))) |> pivot_longer(2:4, names_to = "visit", values_to = paste0("var_", i), names_prefix = paste0("var_", i, "_")) temp } # 两种调用方式均可正常运行 split_to_long("var_1") split_to_long(var_1)
补充说明
{{col}}在select、separate_wider_delim这类tidyverse函数中可以直接识别裸变量名,这是因为这些函数本身支持非标准求值(NSE);- 但当你需要把变量名当作字符串进行拼接、截取等操作时,必须显式将符号转换为字符串,否则会因为类型不匹配报错。
内容的提问来源于stack exchange,提问作者LucaS
相关产品推荐
相关产品推荐

