该如何处理?
d <- data.table(
a = c(1, 2, 3)
)
a <- 2
d[a == a]
给予:
a
1: 1
2: 2
3: 3
预期结果是:
a
1: 2
答案 0 :(得分:5)
我也无意中沦为猎物。通常,这与范围界定有关,而不仅仅是data.table
(dplyr
会做同样的事情)。通过定义一个在父(或全局)环境中掩盖同名变量的变量,您可以在function
正文中发现类似的问题。
a <- 1
# a brain-dead example
myfunc <- function() {
a <- 2
a - a
}
在该function
示例中,“显而易见”的是a
到底是哪个模棱两可,但实际上在您的问题中是同一回事。不安全地假设不等式的LHS或RHS总是在数据内部 ,而另一个在外部 always 如果找不到任何内容,则搜索从内部开始,向外部移动。由于LHS和RHS都位于==
的两侧,因此LHS和RHS都使用'inside'。
我想知道是否很难说出“如果在LHS上找到它的“内部”,那么不要在RHS上看到它的“内部”” ,但是我认为这没有必要复杂。尤其是因为搜索变量是在R的常规变量搜索中有效完成的,因此不必在包装代码中手动编码。
最佳答案?不要这样解决方法?之一:
# this "should" always work, assuming "where" the external variable is defined
d[a == get("a", envir=parent.frame())]
# this only works if it is truly in the global environment
d[a == get("a", envir=globalenv())]
# and @nicola's suggestion:
d[a == evalq(a, envir=parent.frame())]
答案 1 :(得分:2)
对此问题有两种替代解决方案:..
符号前缀和使用setkey()
。
为了进行测试,使用了更复杂的示例数据集,其中2
的值a
位于行2中不是 。
library(data.table)
d <- data.table(rn = 1:4, a = c(1, 4, 3, 2)) # a more subtle test case
a <- 2
d
rn a 1: 1 1 2: 2 4 3: 3 3 4: 4 2
..
符号前缀根据data.table NEWS on version 1.10.2 (Jan 2017):
当
j
是前缀为..
的符号时,它将在呼叫中进行查找 范围及其值应作为列名或数字。
不幸的是,当前仅适用于j=
参数,而不适用于i=
参数。 (根据data.table NEWS on version 1.11.0, May 2018, new features item 18,它可能还会扩展为出现在i=
和by=
中的符号。)
但是,我们可以使用它来创建逻辑值向量或索引向量,以用于后续子集:
library(magrittr)
d[, a == ..a] %>% d[.]
rn a 1: 4 2
或
d[, .I[a == ..a]] %>% d[.]
rn a 1: 4 2
对于子集,magrittr
样式 piping 被用作..
符号前缀,尚未实现在i=
中使用。因此,将d[, a == ..a]
直接用作i=
参数(即d[i = d[, a == ..a]]
)将不起作用(返回未分配的d
)。
setkey()
对于使用局部变量d
,a
过滤setkey()
的不太普遍的用例
可以使用:
setkey(d, a)
d[a]
rn a 1: 4 2
get("a", pos = 1L)
get("a", pos = 1L)]
或更短的get("a", 1L)
是r2evans' answer中已经建议的get("a", envir=parent.frame()
的缩写。
get("a", 1L)
在某种程度上等效于..a
,但由于可以直接在i=
中使用而更加健壮:
d[a == get("a", 1L)]
rn a 1: 4 2