如何实现data.table中基于用户指定列的动态匹配关联?
动态指定data.table关联匹配列的解决方案
问题背景
现有示例data.table数据:
givendata <- data.table(class = c("a", "b", "c", "d", "e", "f", "g"), type = c("x", "z", "y", "x", "x", "z", "z"), risk = c("l", "m", "n", "l", "e", "n", "n"))
关联映射表:
map<-data.table(fx=c('x','y','z','l','m','n','a','b','c','d','e','f','g'),value = runif(13))
静态关联代码可正常运行,实现risk列与map的fx列匹配并新增value2列:
givendata[map, value2 := i.value, on = .(risk = fx)]
但需要动态指定匹配列:匹配列通过读取Excel文件获取,代码如下:
columnname<-read.xlsx(xlsxFile="//C:/xyz.xlsx", namedRegion="inputcolname", colNames=FALSE)[,1]
尝试以下两种写法均失败:
givendata[map, value2 := i.value, on = .(get(columnname)= fx)]
givendata[map, value2 := i.value, on = .(givendata[, x ,env = list(x=columnname)]= fx)]
解决方案
在data.table的on参数中使用动态列名,需通过命名列表构造关联条件,以下两种写法均可实现需求:
写法1:用setNames构造关联列表
# 构造关联条件:将动态列名对应到map的fx列 on_condition <- setNames(list("fx"), columnname) # 执行关联更新 givendata[map, value2 := i.value, on = on_condition]
写法2:用非标准求值语法直接构造
# 需先确保已安装rlang包,若未安装可运行install.packages("rlang") givendata[map, value2 := i.value, on = list(!!columnname := "fx")]
这里的!!是rlang包的语法,用于把变量columnname的实际值作为列名传入on参数的关联条件中。
原理说明
data.table的on参数接受命名列表,规则是:列表名称为givendata中的待匹配列名,列表值为map中的关联列名。之前的写法错误在于试图在.()内部直接用get()或列取值操作,不符合on参数的语法要求。
内容的提问来源于stack exchange,提问作者Mohit
相关产品推荐
相关产品推荐

