2012-09-21 12 views
5

Tengo un data.frame en el que cada gen nombre se repite y contiene valores para 2 condiciones:Calcular la diferencia Transcurrirá pares de filas consecutivas en una trama de datos - 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 

quiero para calcular si hay es un aumento o disminución en "conteo" después del tratamiento y los marca como tal y/o los subconjunta. Es decir (pseudocódigo):

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

Esto lo que debe ser similar en el extremo (las últimas columnas es opcional):

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 

que se han bañado mi cerebro con esto, incluyendo jugar con ddply, y no he podido encontrar una solución - por favor, un desventurado biólogo.

Saludos.

Respuesta

5

La solución plyr sería algo como:

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 
> 

También se podría pensar en hacer esto con un paquete diferente y/o con datos en una forma diferente:

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, funcionó! Tenía la sensación de que podría ser parte de la respuesta, pero no creo que alguna vez se me ocurriera el reg.fun. Aclamaciones. – fridaymeetssunday

+0

@krespim Y aquí hay un [benchmark] (http://stackoverflow.com/revisions/11463757/3) de agrupación de pares de filas que compara plyr con data.table. –

3

Algo como esto :

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 
Cuestiones relacionadas