在data.table中,我们可以根据行号或条件选择行:
> x <- data.table(letters[1:4], 1:4)
> x
V1 V2
1: a 1
2: b 2
3: c 3
4: d 4
> x[2]
V1 V2
1: b 2
> x[V1 == "d"]
V1 V2
1: d 4
但是,我无法同时选择行号和条件:
> x[!2 & V2 > 1]
Empty data.table (0 rows) of 2 cols: V1,V2
这可能是因为!2
未被解释为此格式的行号。我知道我可以将这两个条件联系起来:
> x[!2][V2 > 1]
V1 V2
1: c 3
2: d 4
但是,我想为此子集
分配新的列值x[!2][V2 > 1, V3 := "more"]
现在它只为中间链式data.table创建了列。我可以保存中间表然后合并回原始表,但这将是麻烦的。
实际上我常常觉得data.table
需要一个正确的行号。 .I
是一个依赖于组的动态数字,但我想要一个可以识别每一行的唯一ID,这个唯一ID在合并/加入时非常有用(通常数据不具有唯一ID) 。如果.i
是行号,我可以使用
x[(.i != 2) & (V2 >1), V3 := "more"]
我可以通过先显式创建一个行号列来模拟这个。
另一种方法是对子集data.table进行修改,然后应用原始表。假设我们将x作为原始表,x [!2]作为子集,那么如果x[!2]
上的修改实际修改x,我的问题也将得到解决。当然,这种子集需要以不同的方式创建,例如x[!2, refOriginal = TRUE]
。
答案 0 :(得分:2)
以下是我对解决方案的两次尝试:第一次尝试使用data.table
的汇总语法来计算使用行号.I
的逻辑向量和位置i
的条件以进行子集化和更新列;第二个使用which
和setdiff
从条件中删除某些行号,如果另一方面您需要对行号和条件进行and
操作,setdiff
可以替换为union
:
x[x[, .I != 2 & V2 > 2], V3 := "more"]
x
# V1 V2 V3
# 1: a 1 NA
# 2: b 2 NA
# 3: c 3 more
# 4: d 4 more
x[setdiff(which(V2 > 2), c(2)), V3 := "more"]
x
# V1 V2 V3
# 1: a 1 NA
# 2: b 2 NA
# 3: c 3 more
# 4: d 4 more