2016-07-11 6 views
1

Ich habe einen Datenrahmen, der mehrere Beobachtungen aus der Kontrolle und den experimentellen Kohorten mit Replikaten für jedes Subjekt enthält. HierWie koppelt man Zeilen in einem Datenrahmen mit vielen Spalten unter Verwendung von dplyr in R?

ist ein Beispiel für meinen Datenrahmen:

subject cohort replicate val1 val2 
    A  control  1  10  0.1 
    A  control  2  15  0.3 
    A  experim  1  40  0.7 
    A  experim  2  45  0.9 
    B  control  1  5  0.3  
    B  experim  1  30  0.0 
    C  control  1  50  0.5 
    C  experim  1  NA  1.0 

Ich mag würde jede Steuer Beobachtung paaren mit seinem entsprechenden experimentellem einem für jeden Wert, das Verhältnis zwischen den Paaren zu berechnen. Die gewünschte Ausgabe wird in etwa wie folgt aussehen:

subject replicate ratio_val1 ratio_val2 
    A   1   4    7 
    A   2   3    3 
    B   1   6    0 
    C   1   NA    2 

Im Idealfall würde ich dies mit dplyr und Leitungen realisiert sehen möchten.

Antwort

1

Wir data.table durch Umformen des Datensatzes auf ‚breit‘ Format verwenden können.

library(data.table) 
dcast(setDT(df1), subject+replicate~cohort, value.var = c("val1", "val2"))[, 
      paste0("ratio_", names(df1)[4:5]) := Map(`/`, .SD[, 
     grep("experim", names(.SD)), with = FALSE], 
     .SD [, grep("control", names(.SD)), with = FALSE])][, (3:6) := NULL][] 
# subject replicate ratio_val1 ratio_val2 
# 1:  A   1   4   7 
# 2:  A   2   3   3 
# 3:  B   1   6   0 
# 4:  C   1   NA   2 

oder nach dem mit ‚Gegenstand‘ Gruppieren ‚replicate‘, wir Schleife über die die entsprechenden Elemente von ‚val‘ für ‚experim‘ mit der ‚Kontrolle‘ ‚val‘ Spalten und dividieren

setDT(df1)[, lapply(.SD[, grep("val", names(.SD)), with = FALSE], 
    function(x) x[cohort =="experim"]/x[cohort =="control"]) , 
       by = .(subject, replicate)] 

Oder wir gather/spread von tidyr

library(dplyr) 
library(tidyr) 
df1 %>% 
    gather(Var, Val, val1:val2) %>% 
    spread(cohort, Val) %>% 
    group_by(subject, replicate, Var) %>% 
    summarise(ratio = experim/control) %>% spread(Var, ratio) 
# subject replicate val1 val2 
#  <chr>  <int> <dbl> <dbl> 
# 1  A   1  4  7 
# 2  A   2  3  3 
# 3  B   1  6  0 
# 4  C   1 NA  2 
+0

Genau das, was ich gesucht habe, @akrun! Ich sehe, dass die group_by nur eine Zeile in jeder Gruppe ergibt. Die Alternative wäre also "df1%>% sammeln (Var, Val, val1: val2)%>% verteilen (Kohorte, Val)%>% mutieren (Verhältnis = Experiment/Kontrolle)%>% auswählen (-Kontrolle, -experim)%>% Spread (Var, Ratio) ' – Irakli

+1

genial und fertig! – Irakli

1

können Sie summarize_at Funktion von dplyr verwenden Spalten zusammenfassen val1 und val2, nachdem sie die Daten von subject und replicate Gruppierung. Verwenden Sie [cohort == ...], um die Werte am Experiment und Kontrollgruppe entsprechend für die Division zu holen:

library(dplyr) 
df %>% group_by(subject, replicate) %>% 
     summarize_at(vars(contains('val')), 
        funs("ratio" = .[cohort == "experim"]/.[cohort == "control"])) 

# Source: local data frame [4 x 4] 
# Groups: subject [?] 
# 
# subject replicate val1_ratio val2_ratio 
# <fctr>  <int>  <dbl>  <dbl> 
# 1  A   1   4   7 
# 2  A   2   3   3 
# 3  B   1   6   0 
# 4  C   1   NA   2 
+0

Thank @Psidom verwenden können! Wenn es nur eine Wertespalte gibt, [ist die Antwort so einfach] (http://stackoverflow.com/questions/38295777/how-to-pair-rows-in-a-data-frame-in-r-with- dplyr). Gibt es eine einfache Lösung für den Fall von Spalten mit mehreren Werten? – Irakli

+0

In dplyr 0.4.3 sehe ich nicht summarize_at. Meinst du summarize_each? – Irakli

+0

Ich benutze 'dplyr' 0.5.0. Und 'summarize_at' ist eine neue API für' dplyr'. Wenn Sie also Ihr 'dplyr'-Paket aktualisieren, werden Sie es sehen und auch' summarize_each' wird in der Zukunft veraltet sein, während Sie es jetzt noch verwenden können besser an diese neuen APIs gewöhnen. – Psidom

Verwandte Themen