[R-es] Media de elementos tomados uno a uno de un data.frame
Rubén Gómez Antolí
lobo en mucharuina.com
Dom Nov 27 16:16:31 CET 2011
Hola:
Antes de nada, gracias por vuestras respuestas.
El 27/11/11 12:17, oscar.perpinan en upm.es escribió:
> Hola,
>
> Yo lo haría definiendo un data.frame en lugar de una matriz (como ya te
> han aconsejado),
Aclaro que mis datos estaban en un data.frame (como pone en el asunto
del hilo) pero al preparar el ejemplo me fui a una matriz, vaya usted a
saber porque.
Aprovecho para preguntar, ¿porque es mejor utilizar un data.frame en vez
de una matriz? (En mi ignorancia, y hasta el momento en mi corta
trayectoria por R, no he advertido demasiadas diferencias entre los dos
tipos de objetos)
> definiendo una matriz para la estación y usando
> aggregate (como también te han aconsejado). Un posible código es:
>
> vientos <- data.frame(meses = c(rep(1, 5), rep(2, 5), rep(3, 5)), # Meses
> dir = rep(c("Calma", "Norte", "Este", "Sur", "Oeste"), 3), # Dirección
> calma = c(10, 0, 0, 0, 0, 8, 0, 0, 0, 0, 11, 0, 0, 0, 0), # Calma
> vel1 = c(0, 7, 8, 10, 1, 0, 9, 8, 7, 6, 0, 11, 10, 4, 3), # 1 - 5 m/s
> vel2 = c(0, 9, 10, 12, 7, 0, 10, 3, 2, 1, 0, 10, 7, 6, 8)) # 6 - 10 m/s
>
> est = function(x){
> n = (x - 1) %/% 3 + 1
> ests = c('inv', 'pri', 'ver', 'oto')
> res = ests[n]
> res
> }
Vale, entiendo que el objetivo de la función es «cambiar» el número de
los meses por la estación a la que pertenecen. Lo que me pierde es la
definición de «n», ¿restamos 1 para dividir por tres y sumar 1? No lo
pillo, lo siento.
> aggregate(cbind(vel1, vel2) ~ est(meses) + dir, FUN = mean, data = vientos)
Con el ejemplo preparado esto funciona de escandalo, con los datos
reales «medio funciona». Varias cosas:
- Con cbind agrupamos las columnas, en los datos reales tengo:
> dim(Aero.vientos)
[1] 180 16
dieciséis columnas, que no son demasiadas, pero si hubiera muchas más,
¿como podría «pasarlas» a cbind de una tacada?
(Bueno, poco a poco, acabo de pensar -cosa muy importante, pensar- y
probar con as.matrix(Aero.vientos[,3:14]) y funciona aunque las columnas
del resultado vienen señaladas con NA).
- Segundo problema: ejecutando
aggregate(
cbind(as.matrix(Aero.vientos[,3:14])) ~
est(Aero.vientos[["Meses"]]) + Aero.vientos[["Dirección"]],
FUN = mean,
data = Aero.vientos[,1:14]
)
El resultado no es el esperado.
est(Aero.vientos[["Meses"]]) Aero.vientos[["Dirección"]]
1 inv Total
2 oto Total
3 pri Total
4 ver Total
as.matrix(Aero.vientos[, 3:14]) NA NA NA NA
NA
1 11,53333 32,39833 33,41667 12,76000 7,166667
1,8000000
2 10,93333 34,11167 36,10000 12,15667 5,545000
0,9866667
3 13,20000 30,63050 30,52367 12,46711 9,733556
2,8521667
4 15,96667 33,95333 32,14667 10,29500 6,385000
1,0766667
[...]
Solo agrupa por la dirección "Total" -que, precisamente, es una que
quiero eliminar-, cuando hay unas cuantas más:
dimnames(Aero.vientos)[[2]]
[1] "Meses" "Dirección" "Calma" "X01...06" "X06...11"
[6] "X11...16" "X16...21" "X21...26" "X26...31" "X31...36"
[11] "X36...41" "X41...46" "X46...50" "X..50" "Total"
[16] "Nº.de.obs."
Hasta el momento no consigo encontrar solución. Consultando la ayuda de
aggregate he probado varias cosas, como:
aggregate(
cbind(Aero.vientos[,3],Aero.vientos[,4]) #~
#est(Aero.vientos[["Meses"]]),
,list(Dir=Aero.vientos[["Dirección"]]),
FUN = mean, data = Aero.vientos[,1:14]
)
(Si se incorpora la función est(), aggregate falla)
que realiza el agrupamiento por direcciones tal y como quiero pero
obvia, logicamente a la vista del código, la agrupación por estaciones.
¡¡ Opss !! Bien, como voy pensando y probando mientras escribo, he
atinado por prueba y error:
aggregate(
cbind(as.matrix(Aero.vientos[,3:14])),
list(Dir=Aero.vientos[["Dirección"]],
Est=est(Aero.vientos[["Meses"]])),
FUN = mean, data = Aero.vientos[,1:14]
)
Además, respeta el nombre de las columnas.
¿Alguien haría el favor de explicarme porque falla el primero y
«acierta» el último?
> Para la mediana debes usar median y para la desv. estandar sd.
Pues el mismo código anterior falla miserablemente para estas dos
funciones. :^(
> aggregate(
+ cbind(as.matrix(Aero.vientos[,3:14])),
+ list(Dir=Aero.vientos[["Dirección"]],
+ Est=est(Aero.vientos[["Meses"]])),
+ FUN = sd, data = Aero.vientos[,1:14]
+ )
Error en FUN(X[[1L]], ...) :
el argumento(s) no fue utilizado(s) (data = list(Meses = c(1, 1, 1,
1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6,
6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8,
8, 8, 8,
8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10,
10, 10,
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11,
Calls: aggregate ... aggregate.data.frame -> lapply -> FUN -> lapply -> FUN
> En la
> ayuda de aggregate te cuentan como conseguir resultados de varias
> funciones a la vez.
Pues he repasado toda la ayuda y, la verdad, no he visto nada.
> Saludos.
>
> Oscar.
> --
> Enviado desde mi teléfono Android con K-9 Mail. Disculpa mi brevedad
Enviar el correo anterior desde el móvil es, cuando menos, una proeza;
no hay nada que disculpar, al revés, es de ensalzar.
Muchas gracias de nuevo a todos, a ver si alguien me puede dar una pista
para lo que me queda. (Y perdón por el ladrillo que ha quedado)
Salud y Revolución.
Lobo.
Pd: Por cierto Oscar (permíteme tutearte), terminando con esto me lío
con datos de insolación, así que creo que me pelearé con tu paquete
SolaR que tiene una pinta estupenda; si no pregunto es buena señal. ^_^
--
Libertad es poder elegir en cualquier momento. Ahora yo elijo GNU/Linux,
para no atar mis manos con las cadenas del soft propietario.
---------
Desde El Ejido, en Almería, usuario registrado Linux #294013
http://www.counter.li.org
Más información sobre la lista de distribución R-help-es