这是一个示例数据表:
set.seed(100)
> A <- data.table( a = sample(c('x','c','y',''),10, replace = T), b = sample(as.Date(c('2008-12-31','2012-12-31','2013-12-31','2014-12-31','2016-12-31')),10, replace = T) , c = runif(10) )
> A
a b c
1: c 2014-12-31 0.5358112
2: c 2016-12-31 0.7108038
3: y 2012-12-31 0.5383487
4: x 2012-12-31 0.7489722
5: c 2014-12-31 0.4201015
6: c 2014-12-31 0.1714202
7: 2012-12-31 0.7703016
8: c 2012-12-31 0.8819536
9: y 2012-12-31 0.5490967
10: x 2014-12-31 0.2777238
列a包含x,y,c或空。我想按'b'分组并从数据表中排除在该组的任何行中包含至少一个X AND至少一个C的所有组。 X和C出现的顺序并不重要。
在上面的例子中,组'2014-12-31'将被删除,因为它包含c和x(第1,5,6,10行)。同组'2012-12-31'。但是,'2016-12-31'组仍将保留,因为它有一个C,它没有X.
到目前为止我的方法是:
A[ , .( a) ,by = .(b)][ !(a %in% c('x','c') ) ]
但我相信这会删除所有包含'x'OR'c'的行。我有兴趣同时删除至少有一个X和一个C的那些。
谢谢,
答案 0 :(得分:3)
逻辑:无需unique
,只需提取包含b's
或x
的{{1}} y
,然后删除这些条目。
library(data.table)
set.seed(100)
A <- data.table( a = sample(c('x','c','y',''),10, replace = T),
b = sample(as.Date(c('2008-12-31','2012-12-31','2013-12-31','2014-12-31','2016-12-31')),10, replace = T) ,
c = runif(10) )
split(A, A$b)
#$`2012-12-31`
# a b c
#1: y 2012-12-31 0.5383487
#2: x 2012-12-31 0.7489722
#3: 2012-12-31 0.7703016
#4: c 2012-12-31 0.8819536
#5: y 2012-12-31 0.5490967
#$`2014-12-31`
# a b c
#1: c 2014-12-31 0.5358112
#2: c 2014-12-31 0.4201015
#3: c 2014-12-31 0.1714202
#4: x 2014-12-31 0.2777238
#$`2016-12-31`
# a b c
#1: c 2016-12-31 0.7108038
A[!b %in% intersect(b[a == "x"], b[a == "c"])]
# a b c
#1: c 2016-12-31 0.7108038
使用group_by
func <- function(dt){
if (sum(c("x","c") %in% dt$a) != 2)
return(dt)
}
A[ , func(.SD), by = "b"]
答案 1 :(得分:2)
试试这个:
setkey(A, a)
A[!b %in% intersect(A['x', b], A['c', b])]
答案 2 :(得分:0)
更改了答案以显示dplyr
变体
A %>%
group_by(b) %>%
distinct(a) %>%
filter(a %in% c("x","c")) %>%
filter(row_number()>1) %>%
anti_join(A, ., by="b")
按多个b
列分组,例如b1
和b2
A %>%
group_by(b1,b2) %>%
distinct(a) %>%
filter(a %in% c("x","c")) %>%
filter(row_number()>1) %>%
anti_join(A, ., by=c("b1","b2"))