使用get函数指定连接键合并data.table报错如何解决
问题描述
动态传入列名字符串完成data.table两表合并赋值时,代码触发语法报错,无法正常运行。
示例测试代码:
# 构造测试data.table x = data.table("class" = c(1,2,3,4,4,5), "series" = c("a", "aaa", "cc", "a", "aaa", "a")) y = data.table("class2" = c(1,2,3,4,5,5), "range" = c(11, 11, 4, 13, 5, 8)) # 关联列名以字符串形式存储在变量中 var = "class" # 执行合并赋值逻辑 x[y, on = .(get(var) = class2), range := i.range]
运行后报错信息:
Error: unexpected '=' in "x[y, on = .(get(var) ="
报错原因
R语法规定,等号左侧的内容必须是合法的变量标识符,不能直接放置函数调用表达式。
原代码里.(get(var) = class2)的写法,是把get(var)函数调用放在了列表元素的命名位置——这在R的基础语法解析阶段就会触发错误,根本不会进入data.table的内部逻辑判断,和data.table的功能实现无关。
核心矛盾点:on参数中=左侧需要的是列名本身,不是执行函数后返回的列名字符串。
解决方案
- 方案1:用
setNames构造on参数支持的命名字符向量。data.table的on参数原生支持命名向量入参:向量的名称对应当前表(x)的关联列,向量的取值对应外部表(y)的关联列,完全适配动态列名传入的场景。
可运行代码:# 构造关联条件:动态传入的var值"class"为向量名,对应y表的列"class2"为向量值 on_cols <- setNames("class2", var) x[y, on = on_cols, range := i.range] - 方案2:通过
substitute动态构造合法的.()表达式再执行。如果需要保留原生.()的写法兼容性,可以先把动态列名替换为真实的列名对象,再构造出无语法错误的表达式进行解析:
可运行代码:# 替换占位符,构造合法的列名匹配表达式 on_expr <- substitute(left_col = right_col, list(left_col = as.name(var), right_col = as.name("class2"))) x[y, on = eval(on_expr), range := i.range]
内容的提问来源于stack exchange,提问作者userLx
相关产品推荐
相关产品推荐

