data.table存在与函数变量同名列时如何消除变量名歧义
data.table 环境同名变量冲突解决方案
报错核心原因
data.table 在[]内执行表达式时,默认优先查找表内列,其次才会查找外部/函数环境的变量。之前写的corpus[get(source)=="027021335"]触发first argument has length > 1错误,和base包内置的source()函数无关:执行时get()会先拿到表内长度为10的source列,把整列作为变量名传入get(),不符合get()要求首个参数为单长度变量名的规则,因此报错。
可直接使用的正确写法
以下三种写法都能正确引用外部/函数环境中定义的source变量(该变量存储需要过滤的列名字符串,和dplyr中!!rlang::sym(source)的逻辑完全对应),不会被表内同名列干扰:
- 显式指定查找环境,通用性最强
# source为函数/外部环境中定义的变量,值为要过滤的列名,例:source <- "idref" corpus[get(source, envir = parent.frame()) == "027021335"]
- 使用data.table专属
..前缀,明确告知解析器去上层环境查找变量
corpus[get(..source) == "027021335"]
- 绕开data.table内部作用域规则,零冲突写法
corpus[corpus[[source]] == "027021335"]
验证示例
使用提供的dput示例数据测试,以上三种写法均能正确返回idref == "027021335"的对应行:
library(data.table) # 读入示例数据 corpus <- structure(list(idref = c("027021335", "182132870", "221468579", "034574654", "069546592", "159340950", "169800458", "028529413", "076605442", "026762889"), iddoc = c(97466L, 101100L, 103772L, 110039L, 134077L, 55693L, 38787L, 39304L, 73483L, 74350L), nom = c("Méhaut", "Favre", "Guerdjikova", "Diebolt", "Giraud-Héraud", "Charlier", "Moumni", "Henni", "Bonnel", "Callens"), prenom = c("Philippe", "Karine", "Ani", "Claude", "Eric", "Christophe", "Nicolas", "Ahmed", "Patrick", "Stéphane"), order = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0), role = c("supervisor", "supervisor", "supervisor", "supervisor", "supervisor", "supervisor", "supervisor", "supervisor", "supervisor", "supervisor"), Annee_soutenance = c("2011", "2014", "2018", "2009", "2006", "2015", "2012", "2008", "2009", "2010"), source = c("as.character(idref)", "as.character(idref)", "as.character(idref)", "as.character(idref)", "as.character(idref)", "as.character(idref)", "as.character(idref)", "as.character(idref)", "as.character(idref)", "as.character(idref)" ), time_variable = c("as.character(idref)", "as.character(idref)", "as.character(idref)", "as.character(idref)", "as.character(idref)", "as.character(idref)", "as.character(idref)", "as.character(idref)", "as.character(idref)", "as.character(idref)")), row.names = c(NA, -10L), class = c("data.table", "data.frame")) # 定义外部同名变量 source <- "idref" # 执行任意一种写法,均返回目标行 corpus[get(..source) == "027021335"]
内容的提问来源于stack exchange,提问作者Homard
相关产品推荐
相关产品推荐

