La función
tapply
resulta muy útil cuando se quiere aplicar una función a un vector según la categoría a la que pertenezca, esta categoría viene dada por una variable factor.A continuación se presentan algunos ejemplos donde la función
tapply
resulta convenientemente útil.Primero se crean 3 variables con datos artificiales.
set.seed(7) # Para hacer el ejemplo reproducible
age <- sample(20:45, 20, replace = T) # edad
sex <- sample(c("M", "F"), 20, replace = T) # sexo
eth <- sample(c("W", "B"), 20, replace = T) # etnia
tapply(age, sex, mean) # edad media por sexo (sin contar etnia)
## F M
## 27.8 32.7
tapply(age, eth, mean) # edad media por etnia (sin contar sexo)
## B W
## 30.64 29.78
tapply(age, list(sex, eth), mean) # edad media por sexo y etnia
## B W
## F 28.4 27.2
## M 32.5 33.0
table(sex) # ¿cuantas personas por sexo?
## sex
## F M
## 10 10
table(eth) # ¿cuantas personas por etnia?
## eth
## B W
## 11 9
table(sex, eth) # ¿cuantas personas por sexo y etnia?
## eth
## sex B W
## F 5 5
## M 6 4
split(age, sex) # clasificando las edades por sexo
## $F
## [1] 45 23 21 26 28 24 24 22 20 45
##
## $M
## [1] 30 40 45 31 26 40 22 31 34 28
##
split(age, eth) # clasificando las edades por etnia
## $B
## [1] 45 23 26 45 24 31 24 26 40 22 31
##
## $W
## [1] 30 21 40 28 22 34 20 45 28
##
split(age, list(sex, eth)) # # clasificando las edades por sexo y etnia
## $F.B
## [1] 45 23 26 24 24
##
## $M.B
## [1] 45 31 26 40 22 31
##
## $F.W
## [1] 21 28 22 20 45
##
## $M.W
## [1] 30 40 34 28
##
# Algo muy parecido a 'tapply': Mismos resultados, distinto procedimiento
sapply(split(age, sex), mean) # edad media por sexo (sin contar etnia)
## F M
## 27.8 32.7
sapply(split(age, eth), mean) # edad media por etnia (sin contar sexo)
## B W
## 30.64 29.78
sapply(split(age, list(sex, eth)), mean) # edad media por sexo y etnia (formato vector)
## F.B M.B F.W M.W
## 28.4 32.5 27.2 33.0
# Otra forma de hacer lo anterior, se escribe más, pero es más rápido (con
# muchos datos)
unlist(lapply(split(age, sex), mean)) # (Venables and Ripley, 2000, pag.37)
## F M
## 27.8 32.7
unlist(lapply(split(age, eth), mean))
## B W
## 30.64 29.78
unlist(lapply(split(age, list(sex, eth)), mean))
## F.B M.B F.W M.W
## 28.4 32.5 27.2 33.0
# Ahora con tres factores: Agregamos la región
set.seed(7)
region <- sample(c("N", "S", "E", "W"), 20, replace = T)
DF <- data.frame(age, sex, eth, region)
DFfo <- DF[sapply(DF, is.factor)] # selecccionando solo los factores
table(DFfo) # una tabla de frecuencia multifactorial
## , , region = E
##
## eth
## sex B W
## F 0 0
## M 0 1
##
## , , region = N
##
## eth
## sex B W
## F 4 3
## M 2 0
##
## , , region = S
##
## eth
## sex B W
## F 0 1
## M 2 2
##
## , , region = W
##
## eth
## sex B W
## F 1 1
## M 2 1
##
# do.call(table, DFfo) # es lo mismo do.call('table', DFfo) # es lo mismo
# (Venables and Ripley, 2000, pag.38)
# Descriptivos anteriores
tapply(age, list(sex, eth, region), mean) # Edad clasificando por sex, eth y region
## , , E
##
## B W
## F NA NA
## M NA 34
##
## , , N
##
## B W
## F 24.25 21
## M 24.00 NA
##
## , , S
##
## B W
## F NA 28
## M 31 29
##
## , , W
##
## B W
## F 45.0 45
## M 42.5 40
##
DF.F <- expand.grid(lapply(DFfo, levels)) # igual que expand.grid(sapply(DFfo,levels))
# dato curioso, apply(DFfo, 2, levels) no funciona como es debido, da NULL
DF.F$Freq <- as.vector(table(DFfo))
DF.F # Resume de una mejor manera el resultado de table(DFfo)
## sex eth region Freq
## 1 F B E 0
## 2 M B E 0
## 3 F W E 0
## 4 M W E 1
## 5 F B N 4
## 6 M B N 2
## 7 F W N 3
## 8 M W N 0
## 9 F B S 0
## 10 M B S 2
## 11 F W S 1
## 12 M W S 2
## 13 F B W 1
## 14 M B W 2
## 15 F W W 1
## 16 M W W 1
table(DFfo) # Ya lo habiamos visto antes.
## , , region = E
##
## eth
## sex B W
## F 0 0
## M 0 1
##
## , , region = N
##
## eth
## sex B W
## F 4 3
## M 2 0
##
## , , region = S
##
## eth
## sex B W
## F 0 1
## M 2 2
##
## , , region = W
##
## eth
## sex B W
## F 1 1
## M 2 1
##
Referencia
Venables, W. N. and Ripley, B. D. (2000). S Programming. Springer. Statistics and ComputingISBN 0-387-98966-8 (alk. paper)
-->
No hay comentarios:
Publicar un comentario