2016-12-20 5 views
-1

Это пример таблицы данных:г 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) ) 

> 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 

Колонка а содержит либо х, у, с, или пустым. Я хотел бы группировать по 'b' и исключать из таблицы данных все группы, которые содержат хотя бы один X И хотя бы один 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

Не могли бы вы показать желаемый результат для этого примера? Ваша статья ", а другая, в которой отображаются x и c, не важна." мне это не ясно. – Frank

+1

Пример набора данных не уникален, поскольку вы забыли вызвать 'set.seed()'. –

+0

Спасибо. Я хотел сказать «порядок, в котором x и c появляются неважно» – dleal

ответ

3

логика: не нужно group_by, просто извлечь uniqueb's, который содержит либо x или 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

любая причина для downvote ?? –

+0

Ответ тоже выглядит хорошо. –

+1

@ joel.wilson небольшая коррекция, что он хотел исключить группы с 'x' и' c' – manotheshark

2

Попробуйте это:

setkey(A, a) 

A[!b %in% intersect(A['x', b], A['c', b])] 
0

Измененный ответ, чтобы показать dplyr Variant,

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")) 
+0

Спасибо, это удалит все наблюдения с помощью C или X, а не C и X – dleal

+0

. @dleal изменил ответ на опцию 'dplyr', так как была правильно указана опция' data.table' – manotheshark

Смежные вопросы