2016-07-11 24 views

回答

6

data.table,當i是一個符號,它在呼叫範圍內(見?data.table i參數說明)進行評估,而不是data.table。這是因爲我們允許使用另一個data.table(也就是,i)可以將另一個data.table作爲子集(或加入)數據表。

require(data.table) 
dt1 = data.table(x=1:3, y=4:6) 
dt2 = data.table(x=2:3, z=7:8) 

dt1[dt2, on="x"] # dt2 needs to be looked up first in the calling scope 

由於這一特徵,符號需要i()以便它看作是一種表達(相對於一個符號),這足以理解,它需要內進行評估被包裹data.table的框架。即:

dt1[, id := c(TRUE, FALSE, TRUE)] 
dt1[(id)] # rows 1 and 3 

當您使用!<symbol>時,「!」被捕獲並被刪除,表達式的其餘部分首先被評估,然後「!」被引入回..(但,而不將中間數據高效地進行),即,

dt1[!dt2, on="x"] 

通過首先計算爲dt1[dt2, on="x"]匹配行索引,然後獲得對應於所述指數計算匹配行索引「!」通過採取差異。

因此,當與「!」一起使用時,我們需要一個()以及它被看作是與符號相反的表達。

dt1[!(id)] # works 
dt1[(!id)] # also works 

一般而言,相比於使用情況和使用另一個data.table子集劃分的優點子集劃分的邏輯載體,其爲在data.table的柱的這種用法是極其罕見的。


這會成爲一個好很多時獲得更好的範圍規則爲i參數來實現。見#633

1

我們需要把它的框架內,括號內

d [!(b)] 
# a  b 
#1: 2 FALSE 
#2: 3 FALSE 
+0

儘管這提供了OP給出結果的答案,但我發現它與OP的實際問題「不應該這樣工作?」相切。由於缺乏對「爲什麼」的解釋.. – Arun

+0

@阿倫是的,這是有道理的,你的文章給出了很好的解釋。 – akrun