根据行号和条件选择 data.table R 行

dra*_*doc 3 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
Run Code Online (Sandbox Code Playgroud)

但是我不能同时选择行号和条件:

> x[!2 & V2 > 1]
Empty data.table (0 rows) of 2 cols: V1,V2
Run Code Online (Sandbox Code Playgroud)

这可能是因为!2没有被解释为这种格式的行号。我知道我可以链接两个条件:

> x[!2][V2 > 1]
   V1 V2
1:  c  3
2:  d  4
Run Code Online (Sandbox Code Playgroud)

但是我想为这个子集分配新的列值

x[!2][V2 > 1, V3 := "more"]
Run Code Online (Sandbox Code Playgroud)

现在它只为中间链接的 data.table 创建列。我可以保存中间表然后合并回原始表,但这会很麻烦。

其实我经常觉得data.table需要一个合适的行号。.I是一个依赖于组的动态数字,但我想要一个可以识别每一行的唯一 ID,这个唯一 ID 在合并/加入中非常有用(通常数据没有唯一 ID)。如果.i是行号,我可以使用

x[(.i != 2) & (V2 >1), V3 := "more"]
Run Code Online (Sandbox Code Playgroud)

我可以通过首先显式创建行号列来模拟这一点。

另一种方法是将子集 data.table 上的修改应用回原始表。假设我们有 x 作为原始表,x[!2] 作为一个子集,那么如果修改x[!2]实际上修改了 x,我的问题也将得到解决。当然,这种子集需要以不同的方式创建,例如x[!2, refOriginal = TRUE].

Psi*_*dom 5

这是我对解决方案的两次尝试:第一个使用 的汇总语法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
Run Code Online (Sandbox Code Playgroud)