Estructura salarial en España. ¿Están peor pagadas las mujeres?

Para dar respuesta a esta pregunta vamos a analizar los datos de la encuesta de estructura salarial del INE, cuyos últimos microdatos disponibles corresponden al año 2006. Vamos a utilizar el software libre R.

El script de este documento está disponible en script

Carga de datos

El INE proporciona un fichero plano de ancho fijo y un fichero excel con el diseño del registro, dónde se indica el nombre , tamaño y etiqueta de las variables.
El fichero se puede descargar aqui. El fichero contiene información sobre el salario, tipo de ocupación, nivel de estudios, sector de la empresa , etc.

En primer lugar leemos un fichero csv que tiene dos columnas: tamaño del campo y nombre de las variables . Estas columnas las he copiado del fichero excel de diseño del registro.

disenno <- read.csv("http://dl.dropbox.com/u/2712908/dis_registro.csv")

Ahora ya podemos proceder a leer el archivo con los datos.

estructura.salarial <- read.fwf(file = "http://dl.dropbox.com/u/2712908/EES06%20FAWEB.txt", 
    widths = disenno$tam, col.names = disenno$nombre)

# pasamos los nombres de las variables a minúsculas
names(estructura.salarial) <- tolower(names(estructura.salarial))

R considera como variable cuantitativa todo aquello que parece un número. Tenemos que transformar las que no lo sean a factores. Podríamos dejarlo así y utilizar as.factor(variable) para los análisis, pero es preferible especificar las variables de clase factor y sus distintos niveles.
No lo hago con todas, sólo las más relevantes (pereza)

# sexo

estructura.salarial$sexo <- factor(estructura.salarial$sexo, labels = c("Hombre", 
    "Mujer"))


# propiedad o control , público o privado

estructura.salarial$control <- factor(estructura.salarial$control, 
    labels = c("Publico", "Privado"))


# estrato2: tamaño de la unidad. No me queda claro que son los estratos 0
# (incluye todos los estratos) y 4 (incluye estrato 2 y 3)

estructura.salarial$estrato2 <- factor(estructura.salarial$estrato2, 
    labels = c("Incluye todos los estratos", "De 1 a 49", "De 50 a 199", "200 y más", 
        "Incluye estrato 2 y 3"))


# Mercado

estructura.salarial$mercado <- factor(estructura.salarial$mercado, 
    labels = c("Regional", "Nacional", "UE", "Mundial"))


# Convenio

estructura.salarial$convenio <- factor(estructura.salarial$convenio, 
    labels = c("De sector", "Interprovincial", "De empresa", "Centro de trabajo", 
        "Otro"))


# Nacionalidad

estructura.salarial$tipopais <- factor(estructura.salarial$tipopais, 
    labels = c("Española", "Extranjera"))


# Estudios

estructura.salarial$estu <- factor(estructura.salarial$estu, labels = c("Sin estudios", 
    "Primaria", "Secundaria I", "Secundaria II", "FP grado medio", "FP grado superior", 
    "Diplomatura", "Licenciatura  o superior"))


# Tipo Jornada

estructura.salarial$tipojor <- factor(estructura.salarial$tipojor, 
    labels = c("Tiempo Completo", "Tiempo Parcial"))


# Duración contrato

estructura.salarial$tc <- factor(estructura.salarial$tc, labels = c("Indefinido", 
    "Duracion determinada"))


# Edad

names(estructura.salarial)
##  [1] "ordenccc" "ordentra" "nuts1"    "cnace"    "estrato2" "control" 
##  [7] "mercado"  "convenio" "sexo"     "tipopais" "cno1"     "responsa"
## [13] "estu"     "mesanti"  "anoanti"  "tipojor"  "tc"       "val"     
## [19] "van"      "puentes"  "jap"      "jsp1"     "jsp2"     "hextra"  
## [25] "salbase"  "extraorm" "phextra"  "comsal"   "comsaltt" "comsalv" 
## [31] "irpfmes"  "cotiza"   "afecmes"  "dias"     "salbruto" "pextraaf"
## [37] "pextraav" "vesp"     "afecano"  "mescoma"  "diacoma"  "anos2"   
## [43] "factotal"


# cambiamos el nombre de anos2 a gedad, (suena mejor)

names(estructura.salarial)[42] <- "gedad"

estructura.salarial$gedad <- factor(estructura.salarial$gedad, labels = c("Menos de 20", 
    "20-29", "30-39", "40-49", "50-59", "Más de 59"))

En el diseño de registro pone “menos de 19” y luego “ De 20 a 29 ” ¿dónde caen los que tengan 19 años? Opto por poner Menos de 20
Vamos a seleccionar el subconjunto de los trabajadores a tiempo completo en vez de todos los datos. ¿Motivo? No sé, quizá así sea más comparable el nivel salarial

table(estructura.salarial$tipojor)
## 
## Tiempo Completo  Tiempo Parcial 
##          200881           34391 
esalarial <- subset(estructura.salarial, tipojor == "Tiempo Completo")
nrow(esalarial)
## [1] 200881

Resumen de los datos

Siempre es aconsejable un primer vistazo a los datos, aunque me voy a limitar a summary de algunas variables

# seleccionamos variables para el summary
variables <- c("cnace", "estrato2", "control", "mercado", "convenio", 
    "sexo", "tipopais", "cno1", "estu", "mesanti", "tipojor", "tc", "salbase", 
    "salbruto", "gedad")
summary(esalarial[, variables])
##      cnace                              estrato2        control      
##  F045   : 17715   Incluye todos los estratos:   73   Publico: 16218  
##  KK00   : 16718   De 1 a 49                 :76671   Privado:184663  
##  DABC   : 15538   De 50 a 199               :56118                   
##  NN00   : 14331   200 y más                 :66761                   
##  DMN0   : 11866   Incluye estrato 2 y 3     : 1258                   
##  DFGH   : 11286                                                      
##  (Other):113427                                                      
##      mercado                   convenio         sexo       
##  Regional:84391   De sector        :73214   Hombre:133942  
##  Nacional:83839   Interprovincial  :86560   Mujer : 66939  
##  UE      :14852   De empresa       :36868                  
##  Mundial :17799   Centro de trabajo: 3730                  
##                   Otro             :  509                  
##                                                            
##                                                            
##        tipopais           cno1                             estu      
##  Española  :188405   F0     :30541   Secundaria I            :51170  
##  Extranjera: 12476   G0     :25244   Primaria                :38045  
##                      Q0     :23675   Licenciatura  o superior:25777  
##                      N0     :16695   Secundaria II           :21369  
##                      M0     :15784   FP grado superior       :19939  
##                      T0     :13235   Diplomatura             :18761  
##                      (Other):75707   (Other)                 :25820  
##     mesanti                 tipojor                          tc        
##  Min.   : 0.00   Tiempo Completo:200881   Indefinido          :152686  
##  1st Qu.: 2.00   Tiempo Parcial :     0   Duracion determinada: 48195  
##  Median : 5.00                                                         
##  Mean   : 5.15                                                         
##  3rd Qu.: 8.00                                                         
##  Max.   :70.00                                                         
##                                                                        
##     salbase         salbruto              gedad      
##  Min.   :    0   Min.   :    32   Menos de 20: 1643  
##  1st Qu.:  783   1st Qu.: 12653   20-29      :43860  
##  Median :  951   Median : 17705   30-39      :66423  
##  Mean   : 1116   Mean   : 21399   40-49      :51371  
##  3rd Qu.: 1233   3rd Qu.: 26377   50-59      :31895  
##  Max.   :21211   Max.   :312513   Más de 59  : 5689  
##                                                      

Veamos como se distribuye el salario bruto anual

hist(esalarial$salbruto, main = "Histograma\nsalario bruto anual", 
    xlab = "salario bruto en Euros")

plot of chunk unnamed-chunk-6

Aumentamos el número de breaks para ver mejor la distribución

hist(esalarial$salbruto, main = "Histograma\nsalario bruto anual", 
    xlab = "salario bruto en Euros", breaks = 200)

plot of chunk unnamed-chunk-7

Hacemos un boxplot condicionando por sexo para ver si se aprecian diferencias

with(esalarial, boxplot(salbruto ~ sexo))

plot of chunk unnamed-chunk-8

Comparemos el salario bruto en hombres y mujeres

tapply(esalarial$salbruto, esalarial$sexo, summary)
## $Hombre
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##      32   13700   19000   23100   28100  313000 
## 
## $Mujer
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##     536   11000   15400   18100   22800  267000 
## 

Podríamos utilizar un test de diferencia de medias

with(esalarial, t.test(salbruto ~ sexo))
## 
##  Welch Two Sample t-test
## 
## data:  salbruto by sexo 
## t = 78.73, df = 182992, p-value < 2.2e-16
## alternative hypothesis: true difference in means is not equal to 0 
## 95 percent confidence interval:
##  4858 5106 
## sample estimates:
## mean in group Hombre  mean in group Mujer 
##                23059                18077 
## 

Pues el p-valor cercano a 0 nos indica que la diferencia es significativa

¿Qué pasa con el salario bruto anual medio si controlamos por ocupación?
Podríamos utilizar aggregate para calcular las medias para cada combinación con

aggregate(esalarial$salbruto,by=list(esalarial$sexo,esalarial$cno1),mean)

Pero mejor lo vemos gráficamente utilizando interaction.plot

with(estructura.salarial, interaction.plot(cno1, sexo, salbruto, 
    mean, xlab = "Ocupación", ylab = "Salario bruto anual", lwd = 3, col = c("darkred", 
        "darkgreen"), main = "Salario bruto medio\n por sexo y ocupación", 
    legend = FALSE))
legend("topright", legend = c("Hombre", "Mujer"), col = c("darkred", 
    "darkgreen"), lwd = 3)

plot of chunk unnamed-chunk-11

# pendiente hacerlo con ggplot2

Las diferencias de salario se dan en todas las ocupaciones e incluso son más acentuadas en las ocupaciones dónde más se gana.

Veamos por nivel de estudios y por edad

with(estructura.salarial, interaction.plot(estu, sexo, salbruto, 
    mean, xlab = "Nivel de estudios", ylab = "Salario bruto anual", lwd = 3, 
    col = c("darkred", "darkgreen"), main = "Salario bruto medio\n por sexo y nivel de estudios", 
    legend = F))
legend("topleft", legend = c("Hombre", "Mujer"), col = c("darkred", 
    "darkgreen"), lwd = 3)

plot of chunk unnamed-chunk-12

with(estructura.salarial, interaction.plot(gedad, sexo, salbruto, 
    mean, xlab = "Grupos de edad", ylab = "Salario bruto anual", lwd = 3, col = c("darkred", 
        "darkgreen"), main = "Salario bruto medio\n por sexo y grupos de edad", 
    legend = F))
legend("topleft", legend = c("Hombre", "Mujer"), col = c("darkred", 
    "darkgreen"), lwd = 3)

plot of chunk unnamed-chunk-12

Veamos si estas diferencias se dan tiempo según la variable control que indica si el control de la empresa es privado o público

with(estructura.salarial, interaction.plot(control, sexo, salbruto, 
    mean, xlab = "Sector", ylab = "Salario bruto anual", lwd = 3, col = c("darkred", 
        "darkgreen"), main = "Salario bruto medio\n por sexo y sector", legend = F))
legend("topright", legend = c("Hombre", "Mujer"), col = c("darkred", 
    "darkgreen"), lwd = 3)

plot of chunk unnamed-chunk-13

En las otras variables se dan también estás diferencias. Utilizando la mediana en vez de la media los gráficos son muy similares.

Siguientes pasos

  1. Seguir analizando qué otras variables influyen en el salario y si hay interacción.
  2. Gráficos condicionales (lattice,ggplot,googleVis ??) para analizar no solo la media o mediana si no las diferentes distribuciones del salario bruto según sexo y demás variables.
  3. Modelo anova tipo modelo.salario <- lm(salbruto ~ factores,data=esalarial) y luego analizar la tabla anova.