2012-05-22 12 views
7

Eventuali duplicati:
apply a function over groups of columnsmedia ogni 16 colonne in r

Ho un data.frame con 30 righe e tante colonne (1000+), ma ho bisogno di media ogni 16 colonne insieme. Ad esempio, il frame di dati sarà simile a questa (I troncare per renderlo più facile ..):

Col1   Col2   Col3   Col4........ 

4.176   4.505   4.048   4.489 
6.167   6.184   6.359   6.444 
5.829   5.739   5.961   5.764 
. 
. 
. 

Pertanto, non posso aggregare (non ho una lista) e ho provato:

a <- data.frame(rowMeans(my.df[,1:length(my.df)])) 

che mi dà la media di tutti i 1000+ colonne, ma c'è un modo per dire che voglio farlo ogni 16 colonne fino alla fine? (Sono multipli di 16 il numero totale di colonne).

Un punto secondario, meno importante, ma sarebbe utile per risolvere anche questo. I nomi col sono nella seguente struttura:

XXYY4ZZZ.txt 

Una volta che in media le colonne ho solo bisogno di un nuovo nome col solo XXYY come il resto sarà una media fuori. So che potrei usare gsub ma c'è un modo ottimale per fare la media e questa operazione in un colpo solo?

Sono ancora relativamente nuovo a R e quindi non sono sicuro di dove e come trovare la risposta.

+0

concordato con @Joran, le risposte alla mia domanda a cui ci si collega dovrebbero essere prontamente adattabili per rispondere a questa domanda. – Ben

risposta

0

questo funziona per me su un frame di dati molto più piccolo:

rowMeans(my.df[,seq(1,length(my.df),by=16)]) 
+1

stai prendendo la media di solo le colonne in quella sequenza (1, 17, 33, ecc.) Piuttosto che la media del gruppo di colonne 1:16, 17:32 ecc. – Justin

+0

Ciao Justin, sto prendendo il media delle colonne 1:16 poi da 17 a 32 e così via. Bob e Ben e Joran, grazie per le risposte! Proverò cose diverse e vedrò come va. – david

+0

Siamo spiacenti. Non ho letto la domanda –

5

Ecco un esempio tratto dal @ domanda di Ben e @ risposta di TylerRinker da apply a function over groups of columns. Dovrebbe essere in grado di applicare qualsiasi funzione su una matrice o frame di dati a intervalli di colonne.

# Create sample data for reproducible example 
n <- 1000 
set.seed(1234) 
x <- matrix(runif(30 * n), ncol = n) 

# Function to apply 'fun' to object 'x' over every 'by' columns 
# Alternatively, 'by' may be a vector of groups 
byapply <- function(x, by, fun, ...) 
{ 
    # Create index list 
    if (length(by) == 1) 
    { 
     nc <- ncol(x) 
     split.index <- rep(1:ceiling(nc/by), each = by, length.out = nc) 
    } else # 'by' is a vector of groups 
    { 
     nc <- length(by) 
     split.index <- by 
    } 
    index.list <- split(seq(from = 1, to = nc), split.index) 

    # Pass index list to fun using sapply() and return object 
    sapply(index.list, function(i) 
      { 
       do.call(fun, list(x[, i], ...)) 
      }) 
} 

# Run function 
y <- byapply(x, 16, rowMeans) 

# Test to make sure it returns expected result 
y.test <- rowMeans(x[, 17:32]) 
all.equal(y[, 2], y.test) 
# TRUE 

È possibile fare altre cose strane con esso. Ad esempio, se si ha bisogno di conoscere la somma totale di ogni 10 colonne, avendo cura di togliere NA s se presenti:

y.sums <- byapply(x, 10, sum, na.rm = T) 
y.sums[1] 
# 146.7756 
sum(x[, 1:10], na.rm = T) 
# 146.7756 

O trovare le deviazioni standard:

byapply(x, 10, apply, 1, sd) 

Aggiornamento

by può anche essere specificato come un vettore di gruppi:

byapply(x, rep(1:10, each = 10), rowMeans) 
+0

Ciao jthetzel, grazie mille! questo ha funzionato bene. Ho pensato che, a causa dei miei livelli R di base, ci sarebbe voluto più tempo, ma in realtà è andato molto liscio ... grazie ancora! – david

+0

Grazie mille per l'aggiornamento !! questi sono tutti commenti utili !! – david