2012-09-21 18 views
5

Ho una data.frame in cui ciascuna gene viene ripetuto e contiene valori per 2 condizioni:Calcolare la differenza betwen coppie di righe consecutive in un frame di dati - R

df <- data.frame(gene=c("A","A","B","B","C","C"), 
condition=c("control","treatment","control","treatment","control","treatment"), 
count=c(10, 2, 5, 8, 5, 1), 
sd=c(1, 0.2, 0.1, 2, 0.8, 0.1)) 

    gene condition count sd 
1 A control 10 1.0 
2 A treatment  2 0.2 
3 B control  5 0.1 
4 B treatment  8 2.0 
5 C control  5 0.8 
6 C treatment  1 0.1 

voglio calcolare se ci è un aumento o una diminuzione del "conteggio" dopo il trattamento e contrassegnali come tali e/o sottoinsiemi. Questo è (pseudo codice):

for each unique(gene) do 
    if df[geneRow1,3]-df[geneRow2,3] > 0 then gene is "up" 
     else gene is "down" 

Questo quello che dovrebbe essere simile alla fine (le ultime colonne è facoltativo):

up-regulated 
gene condition count sd regulation 
B control  5 0.1 up 
B treatment 8 2.0 up 

down-regulated 
gene condition count sd regulation 
A control  10 1.0 down 
A treatment 2 0.2 down 
C control  5 0.8 down 
C treatment 1 0.1 down 

mi sono stati rastrellando il mio cervello con questo, compreso il gioco con ddply, e non ho trovato una soluzione, per favore un biologo sfortunato.

Cheers.

risposta

5

La soluzione plyr sarebbe simile:

library(plyr) 
reg.fun <- function(x) { 
    reg.diff <- x$count[x$condition=='control'] - x$count[x$condition=='treatment'] 
    x$regulation <- ifelse(reg.diff > 0, 'up', 'down') 

    x 
} 

ddply(df, .(gene), reg.fun) 


    gene condition count sd regulation 
1 A control 10 1.0   up 
2 A treatment  2 0.2   up 
3 B control  5 0.1  down 
4 B treatment  8 2.0  down 
5 C control  5 0.8   up 
6 C treatment  1 0.1   up 
> 

Si potrebbe anche pensare a fare questo con un pacchetto diverso e/o con i dati in una forma diversa:

df.w <- reshape(df, direction='wide', idvar='gene', timevar='condition') 

library(data.table) 
DT <- data.table(df.w, key='gene') 

DT[, regulation:=ifelse(count.control-count.treatment > 0, 'up', 'down'), by=gene] 

    gene count.control sd.control count.treatment sd.treatment regulation 
1: A   10  1.0    2   0.2   up 
2: B    5  0.1    8   2.0  down 
3: C    5  0.8    1   0.1   up 
>  
+0

Brillante, ha funzionato! Ho avuto la sensazione che ddply potrebbe essere parte della risposta, ma non credo che mi verrebbe in mente il reg.fun. Saluti. – fridaymeetssunday

+0

@krespim Ed ecco un [benchmark] (http://stackoverflow.com/revisions/11463757/3) di raggruppamento di coppie di righe che confronta plyr a data.table. –

3

Qualcosa di simile :

df$up.down <- with(df, ave(count, gene, 
       FUN=function(diffs) c("up", "down")[1+(diff(diffs) < 0) ])) 
spltdf <- split(df, df$up.down) 

> df 
    gene condition count sd up.down 
1 A control 10 1.0 down 
2 A treatment  2 0.2 down 
3 B control  5 0.1  up 
4 B treatment  8 2.0  up 
5 C control  5 0.8 down 
6 C treatment  1 0.1 down 
> spltdf 
$down 
    gene condition count sd up.down 
1 A control 10 1.0 down 
2 A treatment  2 0.2 down 
5 C control  5 0.8 down 
6 C treatment  1 0.1 down 

$up 
    gene condition count sd up.down 
3 B control  5 0.1  up 
4 B treatment  8 2.0  up 
Problemi correlati