select data.table R行基于行号和条件

时间:2016-09-10 03:44:05

标签: r data.table

在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]

1 个答案:

答案 0 :(得分:2)

以下是我对解决方案的两次尝试:第一次尝试使用data.table的汇总语法来计算使用行号.I的逻辑向量和位置i的条件以进行子集化和更新列;第二个使用whichsetdiff从条件中删除某些行号,如果另一方面您需要对行号和条件进行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