2012-05-22 13 views
7

Duplicar posibles:
apply a function over groups of columnspromedio de cada 16 columnas en I

Tengo un data.frame con 30 filas y columnas muchos (1000), pero necesito un promedio de cada 16 columnas juntos. Por ejemplo, la trama de datos se verá así (trunco ​​para que sea más fácil ..):

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 
. 
. 
. 

Por lo tanto, no puedo agregar (no tengo una lista) y yo intentado:

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

que me da el promedio de los más de 1000+ coumns, pero ¿hay alguna manera de decir que quiero hacer eso cada 16 columnas hasta el final? (son múltiplos de 16 el número total de columnas).

Un punto secundario, menos importante pero sería útil para resolver esto también. Los nombres col están en la siguiente estructura:

XXYY4ZZZ.txt 

Una vez promediaron las columnas único que necesito es un nuevo nombre de col con sólo el XXYY que el resto será promediado a cabo. Sé que podría usar gsub, pero ¿hay una manera óptima de hacer el promedio y esta operación de una vez?

Todavía soy relativamente nuevo en R y, por lo tanto, no estoy seguro de dónde y cómo encontrar la respuesta.

+0

de acuerdo @Joran, las respuestas a mi pregunta a la que se vincule deberían ser fácilmente adaptables para responder a esta pregunta. – Ben

Respuesta

0

Esto funciona para mí en una trama de datos mucho más pequeño:

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

está tomando la media de solo las columnas en esa secuencia (1, 17, 33, etc.) en lugar de la media del grupo de columnas 1:16, 17:32, etc. – Justin

+0

Hola, Justin, estoy tomando el media de las columnas 1:16, luego de 17 a 32 y así sucesivamente. Bob, Ben y Joran, ¡gracias por las respuestas! Voy a probar cosas diferentes y ver cómo va. – david

+0

Lo siento. Leer mal la pregunta –

5

Aquí es un ejemplo adaptado de la pregunta de @ @ Ben y la respuesta de TylerRinker de apply a function over groups of columns. Debería poder aplicar cualquier función sobre una matriz o marco de datos por intervalos de columnas.

# 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 

Puede hacer otras cosas extrañas con él. Por ejemplo, si se necesita saber la suma total de cada 10 columnas, asegurándose de eliminar NA s si está presente:

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

O encontrar las desviaciones estándar:

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

actualización

by también se puede especificar como un vector de grupos:

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

Hola jthetzel, ¡muchas gracias! esto funcionó bien. Pensé que debido a mis niveles R básicos habría llevado más tiempo, pero en realidad fue muy fácil ... ¡gracias de nuevo! – david

+0

¡Muchas gracias por la actualización! estos son todos comentarios útiles !! – david

Cuestiones relacionadas