在data.table中使用grep进行子设置 - 不可预测

时间:2016-03-10 11:43:09

标签: r data.table

为什么" grep"在下面的data.table调用中导致问题。

set.seed(45)
dt <- data.table(
    col1 = sample(letters[1:2],10, replace=TRUE), 
    col2=sample(letters[1:5], 10, replace=TRUE),
    col3=runif(10,1,5))

这样的子集,有效:

dt[col1=="b" & col2=="b",] # Works
    col1 col2     col3
1:    b    b    1.5166

但是这会抛出警告并返回错误的数据(或者没有警告和错误的数据)

dt[grep("b", col1) & col2=="b",] # does not
# with seed = 42
> Warning message: In grep("b", col1) & col2 == "b" :   longer object
> length is not a multiple of shorter object length
# with seed = 45
   col1 col2     col3
1:    b    b 1.516600
2:    a    b 3.342007
3:    a    b 1.865772

我可以通过将子集绑在一起来避免这种混淆:

dt[grep("b", col1),][col2=="b",]

但那不是很优雅。

PS。我想问题与here

不同

1 个答案:

答案 0 :(得分:4)

grep的输出是数字vector。它可以是length在0到原始vector长度之间的任何位置,具体取决于有多少匹配。但是,如果我们使用grepl,则返回vectorlogical,并且它始终与原始向量具有相同的length。如果没有匹配项,则唯一的区别是它将全部为FALSE。在这方面,下面的代码应该可以正常工作。

dt[grepl("b", col1) & col2=="b"]