我正在使用的数据表就像
require(data.table)
set.seed(2)
dt <- data.table(user=c(rep('a', 3), rep('b', 2), rep('c', 4)),
type=c(sample(LETTERS[1:4], 3),
sample(LETTERS[1:4], 2),
sample(LETTERS[1:4], 4))
)
是
user type
1: a A
2: a C
3: a B
4: b A
5: b C
6: c D
7: c A
8: c B
9: c C
我想在A
,B
或C
中找到类型的特定用户。在上面的示例中,用户c
不合格,因为他的某个类型记录中有D
。所以期望的输出应该是
user type
1: a A
2: a C
3: a B
4: b A
5: b C
我认为第一种方法显然效率低下,dt
与split(dt, dt$user)
分开,检查grepl
和nrow
是否相同,然后编制索引和rbindlist
。由于我实际使用的数据表有10989251行,因此有必要进行子集化。
答案 0 :(得分:4)
由&#39;用户&#39;,if
all
按&#39;类型&#39;中的元素分组。只有前三个LETTERS
,我们得到Data.table的子集(.SD
)。在这里,我使用%chin%
进行矢量比较,因为它是针对%in%
向量优化的character
的更快版本。
dt[, if(all(type %chin% LETTERS[1:3])) .SD, by = user]
# user type
#1: a A
#2: a C
#3: a B
#4: b A
#5: b C
答案 1 :(得分:1)
使用经典的过滤器选择:
dt[unlist(by(type, user, function(x) !!cumprod(x %in% LETTERS[1:3]))),]
# user type
#1: a A
#2: a C
#3: a B
#4: b A
#5: b C
答案 2 :(得分:0)
有些人可能会发现这种方式不那么优雅,但可能会更快:找到类型为D的用户,然后将其排除。如果没有或很少有重复的用户类型对,可以跳过唯一。
badusers = dt[type=='D',unique(user)];
dt.ABCs = dt[!user %in% badusers,];