2015-02-04 3 views
8

sagen, wir haben diese Daten:Summarize (Anzahl/Freq) nach Art der Behandlung, wo Einzelpersonen beiden Behandlungen erhalten könnten

dat<-data.frame(id=c(1,1,2,2,3,4,4,5,6,6),Rx=c(1,2,1,2,1,1,1,2,2,2)) 

    id Rx 
1 1 1 
2 1 2 
3 2 1 
4 2 2 
5 3 1 
6 4 1 
7 4 1 
8 5 2 
9 6 2 
10 6 2 

Wo Id die Subjekt-ID ist, und Rx ist die Behandlung, die sie erhalten hat. Daher gibt es wiederholte Beobachtungen und die Behandlung kann konsistent oder nicht konsistent sein.

ich in der Lage sein wollen, zusammenfassen, wie viele Probanden erhielten nur Rx 1 erhielt nur Rx 2, und wie viele empfangene Rx 1 und 2

Ich würde eine dplyr Lösung bevorzugen, aber data.table und base R würde geht auch gut. Ich dachte, so etwas wie:

Rx Count 
    1  2 
    2  2 
Both  2 

Danke:

dat %>% 
    group_by(id,Rx) %>% 
    unique() %>% 
    ...something 

Das Endergebnis so etwas wie sein sollte!

+0

Haben Sie die Lösung auf mehr als zwei Arten von Behandlungen verallgemeinern wollen? – davechilders

+0

Das eigentliche Problem hat nur zwei Behandlungen, damit es nicht schrecklich ist, dass es verallgemeinert, sondern als Lernerfahrung und für die spätere Anwendung würde es schätzen, wenn es auf> 2 Behandlungen verallgemeinert. –

Antwort

5

Hier ist eine andere verallgemeinerte Lösung

library(dplyr) 
dat %>% 
    group_by(id) %>% 
    summarise(indx = toString(sort(unique(Rx)))) %>% 
    ungroup() %>% 
    count(indx) 

# Source: local data table [3 x 2] 
# 
# indx n 
# 1 1, 2 2 
# 2 1 2 
# 3 2 2 

Mit data.table, ähnlich

library(data.table) 
setDT(dat)[, .(indx = toString(sort(unique(Rx)))), id][ , .N, indx] 
3

Diese Lösung funktioniert nicht verallgemeinern gut auf mehr als 2 Behandlungen:

library(dplyr) 

dat %>% 
    distinct(id, Rx) %>% 
    group_by(id) %>% 
    mutate(
    trt1 = setequal(1, Rx), # change due to comment from @Marat Talipov 
    trt2 = setequal(2, Rx), 
    both = setequal(1:2, Rx) 
    ) %>% 
    ungroup() %>% 
    distinct(id) %>% 
    summarise_each(funs(sum), trt1:both) 

Diese Lösung kürzer ist und mehr als eine Behandlung nicht verallgemeinern:

library(stringr) 

dat %>% 
    group_by(id) %>% 
    mutate(
    rx_list = str_c(sort(unique(Rx)), collapse = ",") 
    ) %>% 
    distinct(id) %>% 
    count(rx_list) 
+1

Re erste Lösung: Sie können 'setequal (XXX, dat $ Rx)' (XXX könnte 1, 2 oder c (1,2)) anstelle von% in% –

+0

Dies ist nicht vollständig korrekt, wenn die Behandlung Ordnung war nicht dasselbe. I.e. Für diesen Datensatz gibt es ein Duplikat 'dat <-data.frame (id = c (1,1,2,2,3,4,4,5,6,6), Rx = c (2,1, 1,2,1,1,1,2,2,2)) ' –

+0

@DMC, für die zweite Lösung, wenn der Auftrag geht 1,2 vs. 2,1, sind separate Gruppen gebildet. Works, wenn Sie 'rx_list' ändern' rx_list = str_c (sortiert (Rx), Kollaps = "") ' –

2

Nicht gerade die Ausgabe, die Sie angegeben haben, aber es ist Basis R, Einzeiler und allgemein:

table(do.call(function(...) paste(...,sep="_"),as.data.frame(table(dat)>0))) 
#FALSE_TRUE TRUE_FALSE TRUE_TRUE 
    2   2   2 

Wenn die Behandlungen mehr als zwei sind, können Sie habe alle möglichen Kombinationen angegeben.

+0

, für etwas anderen Ausgang 'Tabelle (Interaktion (as.data.frame (Tabelle (dat)> 0)))' –

Verwandte Themen