2010-08-24 21 views
6

Sto usando R, e ho due data.frames, A e B. Entrambi hanno 6 righe, ma A ha 25000 colonne (geni) e B ha 30 colonne. Mi piacerebbe applicare una funzione con due argomenti f(x,y) dove x è ogni colonna di A e è ogni colonna di B. Finora sembra che questo:Applicare su due frame di dati

i = 1 
for (x in A){ 
    j = 1 
    for (y in B){ 
     out[i,j] <- f(x,y) 
     j = j + 1 
    } 
    i = i + 1 
} 

Ho due problemi con questo: dalla mia programmazione Python associo tenere traccia dei contatori come questo come crufty, e dal mio programmazione R Io sono nervoso per i cicli. Tuttavia, non riesco a vedere come applicare apply (o anche se dovrei applicare apply) a questo problema e speravo che qualcuno potesse illuminarmi. Ho bisogno di trattare f() come atomico (in realtà è cor.test()) per ora.

+0

A seconda di 'f', sembra simile al prodotto interno. So che con il prodotto esterno è possibile specificare una funzione da utilizzare, ma non so come farlo per il prodotto interno. – James

+1

Esito a suggerire qualsiasi cosa poiché sono un utente R molto nuovo, ma ho avuto un buon successo usando il pacchetto plyr per la manipolazione dei dati. http://had.co.nz/plyr/ – dnagirl

risposta

6

Dal momento che si sta utilizzando i frame di dati, potrebbe essere più veloce da usare lapply o sapply per fare questo (specialmente dato l'ambito delle frame di dati). Ad esempio,

x <- data.frame(col1=c(1,2,3,4), col2=c(5,6,7,8), col3=c(9,10,11,12)) 
y <- data.frame(col1=c(1,2,3,4), col2=c(5,6,7,8)) 
bl <- lapply(x, function(u){ 
    lapply(y, function(v){ 
     f(u,v) # Function with column from x and column from y as inputs 
    }) 
}) 
out = matrix(unlist(bl), ncol=ncol(y), byrow=T) 
1

L'annidamento delle opere applica, non la sintassi più semplice, però.

x<-data.frame(col1=c(1,2,3,4), col2=c(5,6,7,8), col3=c(9,10,11,12)) 
y<-data.frame(col1=c(1,2,3,4), col2=c(5,6,7,8)) 

z<-apply(x,2,function(col,df2) 
      { 
       apply(df2,2,function(col2,col1) 
          { 
           col2+col1 
          },col) 
      },y) 

z 
col1 col2 col3 
[1,] 2 6 10 
[2,] 4 8 12 
[3,] 6 10 14 
[4,] 8 12 16 
[5,] 6 10 14 
[6,] 8 12 16 
[7,] 10 14 18 
[8,] 12 16 20 
+0

Quindi il primo argomento di 'function()' sempre quello a cui si fa riferimento nell'applica, quindi si fornisce il secondo come argomento aggiuntivo. Grazie! La sintassi è OK nella notazione della domanda: 'apply (A, 2, function (a, B) {apply (B, 2, f, a)}, B)' ma ancora, molto più difficile leggere piuttosto che scrivere? Penso che dovrei scrivere un wrapper se f (a, b) non fosse simmetrico ... –

2

Alcuni dati sono

nrows <- 6 
A <- data.frame(a = runif(nrows), b = runif(nrows), c = runif(nrows)) 
B <- data.frame(z = rnorm(nrows), y = rnorm(nrows)) 

Il trucco: ricordano le colonne con expand.grid

counter <- expand.grid(seq_along(A), seq_along(B)) 
f <- function(x) 
{ 
    cor.test(A[, x["Var1"]], B[, x["Var2"]])$estimate 
} 

Ora abbiamo solo bisogno di 1 chiamata a apply.

stats <- apply(counter, 1, f) 
names(stats) <- paste(names(A)[counter$Var1], names(B)[counter$Var2], sep = ",") 
stats 
Problemi correlati