我有一个ID列表,每个ID都有多个事件。数据看起来像一个事件日志,即每行每个ID一个事件。例如:
n.ID=4
n.events=5
set.seed(1234)
df <- setNames(melt(replicate(n.ID, sort(sample(letters[c(1:10)], n.events))))[c(2:3)], c("ID", "Event"))
df
> df
ID Event
1 1 b
2 1 e
3 1 f
4 1 h
5 1 i
6 2 a
7 2 b
8 2 d
9 2 e
10 2 g
11 3 b
12 3 c
13 3 e
14 3 g
15 3 j
16 4 b
17 4 c
18 4 g
19 4 i
20 4 j
我想选择那些符合条件列表的ID,这些ID使用AND或OR。
例如:
标准向量可以是任意长度。
编辑:
我知道百分比%和“|”,但是,
keep.if <- c("b", "c", "g") # This list can be of any length
subset(df, Event %in% keep.if)
ID Event
1 1 b
7 2 b
10 2 g
11 3 b
12 3 c
14 3 g
16 4 b
17 4 c
18 4 g
我只想要结果中有3行的那些,所以我可以对这个结果做一个表,并选择那些Freq == length(keep.if)的ID ......但我想应该有一个更简单,更简洁的方法...
我想我可以采取的OR版本:
unique(subset(df, Event %in% keep.if)$ID)
答案 0 :(得分:1)
我会创建一个table
,然后使用tidyr::spread
创建一个contigency表类型对象。然后我会使用data.table
来简化子设置和逻辑运算:
library(tidyr)
df.table<-as.data.frame(table(df)) %>% spread(Event, Freq)
df.table
ID a b c d e f g h i j
1 0 1 0 0 1 1 0 1 1 0
2 1 1 0 1 1 0 1 0 0 0
3 0 1 1 0 1 0 1 0 0 1
4 0 1 1 0 0 0 1 0 1 1
library(data.table)
##easier to subset with
df.table<-data.table(df.table)
df.table[b & c & g]
ID a b c d e f g h i j
3 0 1 1 0 1 0 1 0 0 1
4 0 1 1 0 0 0 1 0 1 1
df.table[a | h]
ID a b c d e f g h i j
1 0 1 0 0 1 1 0 1 1 0
2 1 1 0 1 1 0 1 0 0 0
这是你在问题中给出的两个例子。您应该可以执行任何您想要的操作。此外,如果您只想知道哪些ID满足您的逻辑(而不是它们的整个列联表),那么:
df.table[b & c & g]$ID
[1] 3 4