Hoy vamos a centrarnos en la generación de tipologías. Si bien no entraremos en detalles epistemológicos, diremos que la construcción de tipologías es una herramienta fundamental para la investigación social. Si bien tienen utilidad como herramienta puramente conceptual, aqui nos centraremos en la construcción de tipologías de carácter empírico, es decir, en estrecha relación con los datos. Pueden encontrar discusiones sumamente interesantes al respecto aquí y aquí.
Para esto, vamos a tomar como ejemplo una operacionalización posible del concepto de “clase social”: el de Erik Olin Wright, particularmente en el esquema en que idenficaba “posiciones contradictorias de clase”. Pero primero, vamos a introducir algunas herramientas en R.
De la lectura de los textos mencionados más arriba, puede concluirse que la construcción de una tipología es básicamente una combinación de otras variables. Así, por ejemplo, la variable “condición de actividad” tal y como es utilizada en nuestro Sistema Estadístico Nacional puede ser pensado como una tipología que combina varias variables:
Trabajó al menos una hora | No trabajó al menos una hora | |
---|---|---|
Buscó trabajo | ///// | Desocupado |
No buscó trabajo | Ocupado | Inactivo |
De esta forma, tenemos que introducir alguna herrmienta que nos
permita realizar este tipo de combinaciones. Vamos a usar una función
que se llama case_when()
. Con frecuencia, cuando
manipulamos datos en R, necesitamos modificar los datos en función de
varias condiciones posibles. Esto es particularmente cierto cuando
estamos creando nuevas variables con la función de mutación de
dplyr.
Veamos el siguiente ejemplo… Hoy vamos a trabajar con la Encuesta Nacional sobre Estructura Social, llevada adelante por el PISAC. Pueden encontrar más información aquí.
> library(tidyverse)
> df <- read_rds('./data/ENES_Personas_M1.rds')
> df %>%
+ group_by(nivel_ed) %>%
+ summarise(n=n())
## # A tibble: 12 × 2
## nivel_ed n
## <fct> <int>
## 1 Menores de 5 años 2160
## 2 Sin instrucción (incluye nunca asistió o sólo asistió a sala de 5) 910
## 3 Primaria/EGB incompleto 5217
## 4 Primaria/EGB completo 3703
## 5 Secundario/Polimodal incompleto 5466
## 6 Secundario/Polimodal completo 4656
## 7 Terciario incompleto 835
## 8 Terciario completo 1410
## 9 Universitario incompleto 1630
## 10 Universitario completo 1520
## 11 Educación especial 100
## 12 NS/NR 3
La variable nivel_ed
tiene demasiadas categorías.
Supongamos que solamente queremos poder separarlas en tres
categorías:
case_when()
para una sola variablePodemos hacer uso de esta instrucción de la siguiente manera:
> df <- df %>%
+ mutate(nivel_ed_agg = case_when(
+ nivel_ed == 'Menores de 5 años' | nivel_ed == 'Sin instrucción (incluye nunca asistió o sólo asistió a sala de 5)' |
+ nivel_ed == 'Primaria/EGB incompleto' | nivel_ed == 'Primaria/EGB completo' |
+ nivel_ed == 'Educación especial' | nivel_ed == 'NS/NR'~ 'Bajo',
+
+ nivel_ed == 'Secundario/Polimodal incompleto' | nivel_ed == 'Secundario/Polimodal completo' ~ 'Medio',
+
+ nivel_ed == 'Terciario incompleto' | nivel_ed == 'Terciario completo' | nivel_ed == 'Universitario incompleto' | nivel_ed == 'Universitario completo' ~ 'Alto'
+ )
+ )
Podemos ver, entonces, que
> df %>%
+ group_by(nivel_ed_agg) %>%
+ summarise(n=n())
## # A tibble: 3 × 2
## nivel_ed_agg n
## <chr> <int>
## 1 Alto 5395
## 2 Bajo 12093
## 3 Medio 10122
Podemos usar case_when
para implementar un tipo de
lógica simple, donde la función solo prueba la condición única y genera
un valor si esa condición es VERDADERA.
Para hacer esto sintácticamente, simplemente escribimos el nombre de la función: case_when().
Luego, dentro del paréntesis, hay una expresión con un “lado izquierdo” y un “lado derecho”, que están separados por una tilde (~).
EL LADO IZQUIERDO ES UNA CONDICIÓN Dentro del
paréntesis de case_when
, el lado izquierdo es una
declaración condicional que debe evaluarse como VERDADERO o FALSO.
Esta condición es la condición que estamos buscando que indica membresía en un caso particular.
Esto casi siempre será un:
>=
)&
,
|
, !
)Básicamente, el lado izquierdo de la expresión debe ser una expresión lógica que se evalúe como VERDADERO o FALSO.
Esta es la “condición de coincidencia” que estamos buscando para que coincida con un “caso” particular.
EL LADO DERECHO PROPORCIONA UN VALOR DE REEMPLAZO El lado derecho de la expresión proporciona el valor de reemplazo.
Entonces, si el lado izquierdo está buscando los valores que
coinciden con un caso particular, el lado derecho de la expresión
proporciona la salida de case_when()
para ese caso.
Así funciona case_when()
si tenemos una sola condición y
caso que estamos buscando. Pero el verdadero poder de
case_when()
aparece cuando lo usa para implementar la
lógica if/else, o la lógica if/elif/else con múltiples casos.
case_when()
como if-elseAquí, veremos la sintaxis que busca una condición y asigna una salida si esa condición es VERDADERA. Pero si la condición es FALSA, genera un valor diferente.
Así, podríamos haber abreviado la operación anterior…
> df <- df %>%
+ mutate(nivel_ed_agg = case_when(
+ nivel_ed == 'Menores de 5 años' | nivel_ed == 'Sin instrucción (incluye nunca asistió o sólo asistió a sala de 5)' |
+ nivel_ed == 'Primaria/EGB incompleto' | nivel_ed == 'Primaria/EGB completo' ~ 'Bajo',
+ nivel_ed == 'Secundario/Polimodal incompleto' | nivel_ed == 'Secundario/Polimodal completo' ~ 'Medio',
+ TRUE ~ 'Alto' ### TODOS LOS CASOS QUE NO CUMPLEN LAS DOS CONDICIONES ANTERIORES...
+ )
+ )
En esta sintaxis para if-else usando case_when, es posible que haya notado la sintaxis VERDADERA en la tercera línea. ¿Por qué necesitamos esto?
Recuerde de la sección anterior que cuando usamos case_when, usamos expresiones de dos lados para evaluar una condición y luego generamos un valor si esa condición es VERDADERA. Si el lado izquierdo es VERDADERO, case_when() genera el valor del lado derecho.
En este ejemplo de sintaxis aquí, la segunda línea codifica el valor VERDADERO en esa expresión final de dos lados. Esto obliga a case_when a generar el “else-output-value” si ninguna de las condiciones anteriores era VERDADERA.
case_when()
con varias variablesAhora que hemos visto dos ejemplos con una condición, veamos cómo funciona case_when() cuando tenemos varios casos.
La sintaxis case_when que prueba diferentes casos es similar a la sintaxis de un caso.
Cuando tenemos múltiples casos, tenemos “una secuencia de fórmulas”. Dicho de otra manera, la sintaxis tendrá una secuencia de múltiples fórmulas para una “condición de prueba” y “salida”.
case_when(
condicion1 ~ valor1,
condicion2 ~ valor2,
condicion3 ~ valor3,
...)
A su vez, cada una de las condiciones pueden ser tan complejas como querramos. Veamos un ejemplo más, antes de empezar con el esquema de clases.
Supongamos que queremos categorizar a hombres y mujeres según sean ocupados, desocupados o inactivos. Podríamos generar algo como lo que sigue:
> df <- df %>%
+ mutate(sexo_cond = case_when(
+ v109 == 'Varón' & estado == 'Ocupado' ~ 'Hombre-Ocupado',
+ v109 == 'Varón' & estado == 'Desocupado' ~ 'Hombre-Desocupado',
+ v109 == 'Varón' & (estado == 'Inactivo'| estado == 'Menor de 10 años') ~ 'Hombre-Inact',
+ v109 == 'Mujer' & estado == 'Ocupado' ~ 'Mujer-Ocupada',
+ v109 == 'Mujer' & estado == 'Desocupado' ~ 'Mujer-Desocupada',
+ v109 == 'Mujer' & (estado == 'Inactivo'| estado == 'Menor de 10 años') ~ 'Mujer-Inact',
+ v109 == 'Otro' & estado == 'Ocupado' ~ 'Otro-Ocupada',
+ v109 == 'Otro' & estado == 'Desocupado' ~ 'Otro-Desocupada',
+ v109 == 'Otro' & (estado == 'Inactivo'| estado == 'Menor de 10 años') ~ 'Otro-Inact'
+
+ ))
De esta forma,
> df %>%
+ group_by(sexo_cond) %>%
+ summarise(n=n())
## # A tibble: 9 × 2
## sexo_cond n
## <chr> <int>
## 1 Hombre-Desocupado 426
## 2 Hombre-Inact 5778
## 3 Hombre-Ocupado 7054
## 4 Mujer-Desocupada 615
## 5 Mujer-Inact 8654
## 6 Mujer-Ocupada 5077
## 7 Otro-Desocupada 1
## 8 Otro-Inact 1
## 9 Otro-Ocupada 4
Generen una variable que cree cuatro grupos de edad (a partir de la
variable v108
): - 0 a 13 - 14 a 35 - 36 - 64 - más de
65
> ###
El objetivo de este notebook es poder realizar una primera operacionalización del concepto abstracto de “clase social”. Para ello vamos a trabajar sobre uno de los esquemas mencionados antes: el de Erik Olin Wright. En realidad, vamos a trabajar sobre una versión inicial que el autor elaboró hacia fines de los años ’70: el enfoque de las posiciones contradictorias de clase. El texto pueden encontrarlo acá.
Un punto muy interesante de este autor es que ha sido sumamente explícito en el proceso de operacionalización: permite observar cómo se va recorriendo el complejo camino de la construcción de las variables, estableciendo un nexo entre lo empírico y lo heurístico.
En este sentido, su perspectiva neomarxista conserva la noción marxista de explotación en las categorías analíticas que elabora y busca definir los indicadores que le permitan interpretar más adecuadamente las variantes empíricas que encuentra en su abordaje a la realidad.
En una apretada síntesis trataremos de referirnos a las premisas conceptuales, a partir de las cuales Wright construye lo que llama “Tipología de las posiciones de clase en la sociedad capitalista”. En primer lugar, establece una distinción entre clase y ocupación. Las ocupaciones deben entenderse como posiciones definidas dentro de las relaciones técnicas de producción, mientras que las clases se definen por las relaciones sociales de producción. ¿Cómo lleva a la práctica ese esquema? ¿Cómo logra construir mediciones de cada uno de los grupos sociales que identifica?
Estableció tres posiciones básicas en las relaciones de clase del capitalismo:
Dado que el contexto en que escribe este primer trabajo, una de las principales preocupaciones había sido la emergencia en el capitalismo contemporáneo de las (mal) llamadas “nuevas clases medias”. Trabajaremos este proceso más adelante, pero lo fundamental aquí es que como resultado de esta preocupación incluyó dos nuevas posiciones:
Tabla 1. Criterios para posiciones de clase en el Estudio de Panel sobre Dinámica de Ingresos
**** | Cuenta propia | Emplea a otros | Supervisa a otros | Influencia sobre pagos de otros | Empleado por otro |
---|---|---|---|---|---|
Empleadores | Sí | Sí | Sí | Sí | No |
Managers | No | No | Sí | Sí | Sí |
Supervisores | No | No | Sí | No | Sí |
Trabajadores | No | No | No | No | Sí |
Pequeña burguesía | Sí | No | No | No | No |
Vemos como los diferentes grupos presentan características que en su mayoría son operacionalizables con la información disponible en gran parte de las encuestas a hogares que se realizan en Argentina.
Así, podríamos mapear la primera dimensión (es cuanta propia) con las categorías ocupacionales “Patrón”, “Trabajador por cuenta propia” y “Trabajador familiar”.
La segunda dimensión, emplea a otros, podría ser aproximada
mediante la categoría de patrones. No obstante, dado que se hace una
pregunta en la ENES, v196
(“Ese negocio/empresa/actividad,
¿emplea/ba personas asalariadas?”) se utilizará esta variable
también.
La tercera dimensión (supervisa a otros) será aproximada por
la pregunta v186
(“¿Forma/ba (…) parte de su empleo
supervisar el trabajo de otros o decirles qué hacer?”)
La quinta dimensión (empleado por otros), será aproximada por la categoría ocupacional (asalariados) que no supervisen a otras personas.
La única excepción es la característica (tiene influencia sobre pagos de otros). Esta variable no está operacionalizada en la ENES por lo cual quedará fuera de nuestro análisis.
Uno de los objetivos del ejercicio es replicar algunos análisis del texto de Erik Olin Wright sobre la relación entre la estructura social y la determinación de ingresos.
Para ello, era necesario reproducir el esquema de clases del autor de la forma más aproximada posible. Veamos, primero, la sintaxis general…
> df <- df %>%
+ mutate(class_eow = case_when(
+ (cat_ocup == 'Patrón' | cat_ocup == 'Cuenta propia' | cat_ocup == 'Trabajador familiar sin remuneración')
+ & (v196 == 'Sí, siempre' | v196 == 'Sólo a veces, por temporadas')
+ & (v186 == 'Sí' | v186 == 'No') ~ 'Empleadores',
+
+ cat_ocup == 'Obrero o empleado'
+ & v186 == 'Sí'
+ & v187 >= 5 ~ 'Managers',
+
+ cat_ocup == 'Obrero o empleado'
+ & (v186 == 'Sí' | v186 == 'NS/NR')
+ & (v187 < 5 | is.na(v187)) ~ 'Supervisores',
+
+ cat_ocup == 'Obrero o empleado'
+ & df$v186 == 'No' ~ 'Trabajadores',
+
+ (cat_ocup == 'Cuenta propia' | cat_ocup=='Trabajador familiar sin remuneración')
+ & (v196 == 'No contrata' | is.na(v196)) ~ 'Pequeña burguesía',
+
+ TRUE ~ 'Sin datos y menores'
+ )
+ )
Para la construcción de la categoría empleadores (ver esquena de Wright 1974 pp. 242-247) se siguieron los siguientes criterios
(cat_ocup == 'Patrón' | cat_ocup == 'Cuenta propia' | cat_ocup == 'Trabajador familiar sin remuneración')
& (v196 == 'Sí, siempre' | v196 == 'Sólo a veces, por temporadas')
& (v186 == 'Sí' | v186 == 'No') ~ 'Empleadores`
cat_ocup
) se decidió tomar como criterio definitorio si
contrataban asalariados (v196
) de forma permanente o
eventual, independientemente de si estaban clasificados como patrones,
TCP o familiares.v186
de la ENES y se consideró que si se trataban
de empleadores -y, por ende, patrones-, entonces, sí realizaban tareas
de supervisión, independiente de que hubieran contestado que no.Para la aproximación a la categoría de managers,
cat_ocup == 'Obrero o empleado'
& v186 == 'Sí'
& v187 >= 5 ~ 'Managers',
se consideró a los asalariados que * declararan que realizaban tareas
de control y supervisión -v186
- * que lo hicieran sobre 5 o
más trabajadores (v187
), que constituye la mediana de esta
variable. Este criterio se toma en reemplazo de la pregunta original de
Wright acerca de si los entrevistados tenían voz sobre la definición de
remuneraciones o promociones de las personas que supervisaban.
Los supervisores fueron aproximados
cat_ocup == 'Obrero o empleado'
& (v186 == 'Sí' | v186 == 'NS/NR')
& (v187 < 5 | is.na(v187)) ~ 'Supervisores',
tomando a los asalariados que * declararan que realizaban tareas de
control y supervisión -v186
- * que lo hicieran sobre menos
de 5 trabajadores (v187
)
Los trabajadores
cat_ocup == 'Obrero o empleado'
& df$v186 == 'No' ~ 'Trabajadores',
están constituidos por todos los asalariados que no son ni
managers ni supervisores: aquellos que
no realizan tareas de supervisión ni control sobre otros
-v196
.
La pequeña burguesía
(cat_ocup == 'Cuenta propia' | cat_ocup=='Trabajador familiar sin remuneración')
& (v196 == 'No contrata' | is.na(v196)) ~ 'Pequeña burguesía',
está constituida por todos aquellos autónomos que no contratan asalariados en ningún momento.
¿Qué significa esta línea en el código?
TRUE ~ 'Sin datos y menores'
Vamos a hacer una última modificación: queremos que dentro de
class_eow
podamos identificar a los desocupados que no
presentan información suficiente:
> df <- df %>%
+ mutate(class_eow = case_when(
+ estado == "Desocupado" & class_eow == "Sin datos y menores" ~ "Desocupado s/d",
+ TRUE ~ class_eow
+ ))
De esta forma, podemos tener una primera aproximación a la distribución de clases sociales según el esquema de Erik Olin Wright:
> df %>%
+ group_by(class_eow) %>%
+ summarise(n=n()) %>%
+ mutate(prop = n/sum(n)) %>%
+ ggplot() +
+ geom_col(aes(x=reorder(class_eow, prop), y=prop)) +
+ theme_minimal() +
+ theme(axis.text.x = element_text(angle = 45,hjust=1)) +
+ labs(y='%',
+ x='Clase EOW')
Ahora, filtremos los “sin dato” pero quedémonos solamente con los
desocupados
> df %>%
+ filter(class_eow!="Sin datos y menores") %>%
+ group_by(class_eow) %>%
+ summarise(n=n()) %>%
+ mutate(prop = n/sum(n)) %>%
+ ggplot() +
+ geom_col(aes(x=reorder(class_eow, prop), y=prop)) +
+ theme_minimal() +
+ theme(axis.text.x = element_text(angle = 45,hjust=1)) +
+ labs(y='%',
+ x='Clase EOW')
> write_rds(df, './data/ENES_Personas_M1_EOW.rds')