2009-09-22 22 views
5

¿Cómo agrego los valores de muchas variables?Agregar varias columnas, transformación con múltiples variables

Si sólo tuviera dos variables (columnas) que simplemente podría seguir:

summation.variable <- variable1 + variable2 

o si se trataba de una trama de datos:

transform(dataframe, summation.col = column1 + column2) 

¿Cómo hacerlo si tengo acerca 10 variables y no quiero escribir cada una como en col1 + col2 + col3 + col4. Para empeorar las cosas, mis columnas tienen nombres bastante largos y, a veces, las columnas exactas que uso pueden cambiar. Tengo un vector de caracteres con todos los nombres de columna relevantes, pero no puedo pensar cómo usarlo.

Lo siguiente es inútil ya que agrega cada valor en cada columna en cada fila y le da un valor único para todo el lote.

sum(metrics) 
+0

revise la ortografía de la variable en la línea 2 –

Respuesta

8

que desea utilizar rowSums

tmp <- data.frame(a=1:2,b=3:4,d=5:6) 
rowSums(tmp[,c("a","d")]) 

o, más generalmente, se aplican (véase la indexación con un vector de caracteres.):

apply(tmp[,c("a","d")], 1, sum) 
1

yo acabamos de la respuesta. Sabía que quería algún tipo de suma. Fui a la ayuda de R para buscar "suma". Y allí lo encontré. La respuesta es seguir el enlace "colsums" a "rowSums". Entonces, donde las métricas son un vector de caracteres de los nombres de columna relevantes. La siguiente línea produce un vector donde se agregan todos los números en cada fila.

rowSums(data.frame[metrics]) 

¿Cómo lo haría si uno quisiera que cada valor se multiplicara entre sí? No veo una filaProductos.

+0

Creo que usaría la función aplicar para hacer productos (o alguna otra función), marque? Aplicar – PaulHurleyuk

+0

rowSums es una versión más eficiente de la suma de las solicitudes – Thierry

4

Hay muchas maneras de hacer este tipo de operación (es decir, aplicar una función a través de una fila o columna.), Pero como Eduardo señala, se aplican es el más básico:

tmp <- data.frame(a=1:2,b=3:4,d=5:6) 
apply(tmp, 1, prod) 

Esta es una muy función flexible. Por ejemplo, se puede hacer ambas operaciones a la vez con esta llamada:

apply(tmp, MARGIN=1, function(x) c(sum(x), prod(x))) 

Realizando el mismo análisis a través de columnas es también sencillo (el parámetro MARGEN describe si se utiliza filas o columnas):

apply(tmp, MARGIN=2, function(x) c(sum(x), prod(x))) 
3

Respondiendo a Farrel answer:

En RSeek para rowProd encontré dos paquetes - matrixStats y fUtilities. Puedes mirarlos.

La segunda solución es un poco complicada. Puedes crear tu expresión y evaluarla.

X <- structure(list(
    varA = c(0.98, 0.75, -0.56, -1.43, 0.65, -1.15, -1.52, 0.1, 0.06, 0.76), 
    varB = c(-0.12, -0.6, 0.62, 0.9, -0.44, 0.37, 0.62, 0.76, -1.61, -0.26), 
    varC = c(-0.5, -0.37, -0.43, -0.7, 0.83, -0.24, -0.57, 0.05, -1.31, 0.7), 
    varD = c(-0.06, -0.11, 1.03, -1.76, -0.42, -1.21, -0.62, -1, -1.16, 2.13), 
    varE = c(-1.96, 0.69, -1.85, -1.74, -1.47, 1.24, 0.29, -1.18, 0.89, 0.42), 
    varF = c(0.29, -0.22, -1.29, 1.19, 0.38, -0.23, -0.5, -1.07, -1.83, 0.58), 
    varG = c(0.59, -0.41, -1.37, 0.89, -0.75, 0.95, 0.95, -0.9, 0.71, -1.3) 
), 
    .Names = c("varA", "varB", "varC", "varD", "varE", "varF", "varG"), 
    row.names = c(NA, -10L), class = "data.frame" 
) 

metrics <- c("varB","varC","varF") 

eval(
    parse(text = paste(metrics,collapse=" * ")), 
    envir = X 
) 

Algunas explicaciones:

  • pasta de crear una cadena parece varB * VARC * Varf (colapso es para elementos del vector de la concatenación)
  • de análisis es la de convertir el texto a la expresión
  • eval con envir = X es ejecutar la expresión dentro de X

Para su pregunta original, podría usar col lapse = "+".

editar: si sus variables no están en un data.frame, entonces eval sin envir es suficiente.

Edit2: ejemplos del uso de rowProds de paquetes mencionados:

matrixStats::rowProds(as.matrix(X[,metrics])) # convert to a matrix is needed 
fUtilities::rowProds(X[,metrics]) # without conversion 

I Digg en fuente de estas funciones y:

  • futilidades uso se aplican, por lo que este es el mismo que se aplica (X, 1 , prod) (esto no es una solución eficiente)
  • matrixStats es inteligente y hace algo como exp (rowSums (log (X))), por lo que debería ser más rápido.

Las pruebas de velocidad:

Xm <- matrix(rnorm(50000*8),ncol=8) 
Xd <- as.data.frame(Xm) 

require(fUtilities) 
require(matrixStats) 
system.time(matrixStats::rowProds(as.matrix(Xd))) 
# user system elapsed 
# 0.08 0.02 0.09 
system.time(matrixStats::rowProds(Xm)) 
# user system elapsed 
# 0.08 0.00 0.08 
system.time(fUtilities::rowProds(Xd)) 
# user system elapsed 
# 0.52 0.00 0.52 

Incluso con la conversión a una versión matrixStats matriz es más rápido.

+1

biblioteca (fortunes) ; fortune (106) – Thierry

+0

Quiero usar do.call (f, as.list (X [, metrics])) pero no puedo encontrar una función que funcione como f (a, b, c) = a * b * do. Buen comentario por cierto;) – Marek

+0

Mira 'prod()' – hadley