2016-12-20 35 views
-1

Dies ist ein Beispiel-Datentabelle:r data.table - Gruppen ausschließen, die bestimmte Werte in Zeilen enthalten

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 

Spalte A enthält entweder x, y, c, oder leer ist. Ich möchte nach 'b' gruppieren und aus der Datentabelle alle Gruppen ausschließen, die mindestens ein X UND mindestens ein C in jeder Zeile der Gruppe enthalten. Die Reihenfolge, in der X und C erscheinen, ist nicht wichtig.

In dem obigen Beispiel Gruppe 2014.12.31 "eliminiert werden, weil es c und x (Zeilen 1,5,6,10) enthält. Dasselbe gilt für die Gruppe '2012-12-31'. Allerdings Gruppe ‚2016.12.31‘ bleiben, weil, während es eine C hat, ist es kein X. hat

Mein Ansatz war bisher:

A[ , .(a) ,by = .(b)][ !(a %in% c('x','c')) ] 

Aber ich glaube, dass dies alles würde entfernen die Zeilen mit 'x' ODER 'c'. Ich bin daran interessiert, nur diejenigen mit mindestens einem X und einem C gleichzeitig zu entfernen.

Danke,

+0

Könnten Sie Ergebnis für dieses Beispiel zeigen gewünscht? Ihre Klausel "und die andere, in der x und c erscheinen, ist nicht wichtig." ist mir ohne es nicht klar. – Frank

+1

Der Beispieldatensatz ist nicht eindeutig, da Sie vergessen haben, 'set.seed()' aufzurufen. –

+0

Danke. Ich wollte sagen, „die Ordnung x, in dem und c erscheinen nicht wichtig ist“ – dleal

Antwort

3

Logik: keine Notwendigkeit, group_by, sondern nur die uniqueb's extrahieren, die die Einträge entweder x oder y und entfernen Sie enthält.

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

kein Grund zu downvote ?? –

+0

Antwort sieht auch gut für mich aus. –

+1

@ joel.wilson kleine Korrektur, die er mit 'X' ausschließen Gruppen gesucht und 'c' – manotheshark

2

Try this:

setkey(A, a) 

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

die Antwort geändert unter Verwendung einer dplyr Variante von

A %>% 
    group_by(b) %>% 
    distinct(a) %>% 
    filter(a %in% c("x","c")) %>% 
    filter(row_number()>1) %>% 
    anti_join(A, ., by="b") 

Zur Gruppe b Spalten mehrere zu zeigen, zum Beispiel b1 und 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

Danke, das würde alle Beobachtungen mit C oder X, nicht C und X entfernen – dleal

+0

@ deleal änderte die Antwort auf 'dplyr' Option als die richtige' data.table' Option wurde bereits gegeben – manotheshark

Verwandte Themen