2011-04-05 11 views
5

Tengo 5 columnas de datos numéricos (m1, m2, m3, m4, m5) y quiero generar una nueva columna con el valor medio de todas las m en la misma fila. Es decir:Expresión R para administrar NA al sumar columnas

(m1 + m2 + m3 + m4 + m5)/5 

Tengo un problema con la gestión de los valores de NA: Quiero que el valor medio sea NA si, y sólo si, todos los valores individuales de la década de m son NA. Pero, si uso na.rm, entonces las NA se sustituyen por ceros y no hay NA en la columna de los medios. Por otro lado, si no uso na.rm, la columna de medias es NA si CUALQUIERA de las m es NA.

he hecho lo siguiente:

m <- rowSums(data.frame(m1,m2,m3,m4,m5)/5, na.rm=TRUE) 

for (i in 1:length(m)) { 
    if (all(is.na(c(m1[i],m2[i],m3[i],m4[i],m5[i])))) { 
     m[i] <- NA 
    } 
} 

Funciona, pero estoy casi seguro de que R puede hacerlo de una manera mejor. ¿Cómo se puede hacer sin bucles?

Tal vez la pregunta suena un poco trivial. Perdón por eso, pero soy nuevo en R.

Gracias de antemano.

Respuesta

5

Use rowMeans en lugar de rowSums:

Df <- data.frame(
    m1 = c(NA,1:10,NA), 
    m2 = c(10:5,NA,4:1,NA), 
    m3 = c(11,12,NA,13:20,NA) 
) 
rowMeans(Df,na.rm=T) 
[1] 10.500000 7.333333 5.000000 7.666667 8.000000 8.333333 11.000000 
    9.333333 9.666667 10.000000 10.333333  NA 
3

La respuesta es bastante simple y que vas a patear cuando revelo todo ;-)

Primero un ejemplo reproducible:

set.seed(1) 
dat <- matrix(runif(100*5), ncol = 5) 
## add some random NA 
dat[sample(NROW(dat) * NCOL(dat), 100)] <- NA 
dat <- data.frame(dat) 
names(dat) <- paste("m", 1:5, sep = "") 
## make 1 row all NA 
dat[10, ] <- rep(NA, NCOL(dat)) 

La solución es usar rowMeans() no rowSums():

> rowMeans(dat, na.rm = TRUE) 
    [1] 0.5040661 0.2447789 0.5785721 0.6552587 0.5000273 0.6553183 
    [7] 0.5017969 0.5961018 0.3778305  NA 0.7843261 0.3118411 
[13] 0.6023241 0.7230658 0.4849793 0.3579792 0.65 0.5891246 
[19] 0.5985094 0.6450797 0.5884122 0.3308921 0.4659702 0.3595603 
[25] 0.6291160 0.5420563 0.3555441 0.3922415 0.4554090 0.6912613 
[31] 0.5849739 0.1436432 0.3363359 0.5620860 0.4845476 0.6243143 
[37] 0.6453576 0.3102552 0.6801590 0.5730385 0.6595771 0.4125847 
[43] 0.5950305 0.3908888 0.5228980 0.4290490 0.3219740 0.4941847 
[49] 0.3203416 0.6077816 0.6725149 0.6037703 0.4706785 0.3780164 
[55] 0.2773157 0.2887002 0.5679866 0.5216224 0.4181383 0.4182203 
[61] 0.3985725 0.4043380 0.3024113 0.5441925 0.6163834 0.5365182 
[67] 0.3324975 0.5444736 0.6809868 0.5073465 0.4122997 0.6164483 
[73] 0.4803133 0.3044119 0.2990064 0.5280371 0.5925953 0.6079630 
[79] 0.5144217 0.7415579 0.4059379 0.3966217 0.7344768 0.7502413 
[85] 0.4064067 0.2837371 0.6139601 0.3669062 0.5450748 0.4665940 
[91] 0.3618159 0.4623254 0.5885807 0.4686613 0.4246080 0.6322250 
[97] 0.2747088 0.4716259 0.4306550 0.1015050 

comparar la entrada para la fila 10 utilizando los dos sistemas:

> rowMeans(dat, na.rm = TRUE)[10] 
[1] NA 
> rowSums(dat/5, na.rm = TRUE)[10] 
[1] 0 
+0

La diferencia se debe al hecho que el '> suma (DAT [10,]/5, na.rm = VERDADERO)' devuelve 0, pero 'mean (dat [10,], na.rm = TRUE)' es 'NaN'. Ver '? RowSums' y la sección' Value' que explica lo que está sucediendo. –

+0

Cuál (el anterior) parece contradecir la ayuda - 'mean (rep (NA, 5), na.rm = TRUE)' parece devolver 'NaN' no' NA'. Podría ser un error de documentación. –

Cuestiones relacionadas