Abstract
Este documento de trabajo presenta algunos resultados preliminares: su único objetivo es mostrar la viabilidad general del proyecto a la Escuela de Doctorado de la Universidad de Málaga. No debe considerárselo como un reporte maduro del estudio. Se presenta la base de datos preparada, y una versión inicial del código utilizado para la preparación y análisis de los datos, al igual que algunos resultados preliminares. Debe tenerse en cuenta que la versión del diccionario utilizada en este documento aun se encuentra en fase piloto; por lo tanto, los resultados obtenidos cambiarán en la medida en que el diccionario sea mejorado.En este Proyecto se prepara una base de datos de evaluaciones web a docentes uruguayos y, mediante la aplicación de minería de textos en los datos cualitativos (comentarios y etiquetas), se explora cuantitativamente el vocabulario utilizado por estudiantes para evaluar docentes. Con base en el Proyecto “Teachers´ Soft Skills: a systematic review” y juicio de expertos, el vocabulario se categoriza y se calcula la proporción de SS informadas en cada docente. Se analiza su relación con la calificación de ese docente, cuantificando la importancia que las SS tienen en la evaluación de un “buen” o “mal” docente.
Este es un documento HTML interactivo. En caso de que no pueda verlo, intente descargarlo y abrirlo con Google Chrome, Mozilla Firefox u otro navegador web.
Debajo de cada una de las secciones encontrará -a la derecha- un pequeño botón con la palabra code. Púlselo para ver el código en R correspondiente. En caso de que desee ver todo el código puede utilizar el botón arriba a la derecha del documento.
Extraer mediante herramientas de web scraping las calificaciones, institución, etiquetas y comentarios en las evaluaciones públicas hechas a docentes de Uruguay(n=5.125, n= 3744 con etiquetas, n=3062 con etiquetas y comentarios) en una página web de evaluación docente pública (MisProfesores.com).
Clasificar las etiquetas y los comentarios como “habilidades blandas” y “habilidades técnicas” (cuando corresponda). En los comentarios, clasificar “Calificadores”, palabras que hablan de la satisfacción general con el/la docente. Calcular para cada sujeto la proporción de cada tipo de habilidad, según la calificación de sus estudiantes.
Preparar una base de datos que incluya, para cada docente: nombre, institución, área de estudio, calificación general, etiquetas, proporción de etiquetas que refieren a cualidades técnicas y blandas (considerando su valencia positiva, negativa o ambivalente), proporción de palabras en comentarios referentes a habilidades técnicas/blandas y calificadores.
Analizar diferencias según área del conocimiento y nivel de estudios.
Determinar la relación entre las habilidades (según etiquetas, comentarios) y la calificación general.
¿Hay diferencias en la proporción de cualidades blandas y técnicas adjudicadas (mediante etiquetas y comentarios) entre los distintos niveles de estudio (secundaria, universidad) y áreas de estudio (STEM, CCSS, etc.)?
¿Qué relación hay entre las habilidades (evaluadas según la proporción de etiquetas) y la calificación general?
¿Cuáles son las principales cualidades adjudicadas (mediante etiquetas y comentarios) a los docentes con calificaciones de cuartil 1 y 4?
El proyecto se pre-registró en enero de 2022 en OSF (osf.io/ymzp2)
Estudio mixto, de análisis automatizado de texto.
Se descargó y preparó una base de datos con evaluaciones a docentes uruguayos realizadas en el servicio web MisProfesores.com. La muestra incluye a docentes de todos los niveles, uruguayos, evaluados en dicha plataforma.
Se elabora un diccionario ad hoc categorizando el vocabulario utilizado en comentarios y etiquetas. El mismo se realiza en base a la revisión sistemática de la literatura llevada a cabo en el Proyecto 1, y se valida mediante juicio de expertos y análisis análogos a los usados por Collins et al. (2009).
La descarga de los datos se realiza mediante la herramienta Web Scraper. La preparación y análisis de los datos se realiza en RStudio, utilizando principalmente los paquetes tidyverse y tidytext. Utilizando el paradigma top-down de análisis de texto (Kennedy et al., 2021), se extraen las palabras frecuentes en comentarios y etiquetas y se elabora un diccionario, mediante el cual se calcula la proporción de SS y HS.
Tras este procedimiento, la base de datos incluye para cada docente (observación) los siguientes campos: calificación general, proporción de HS/SS en etiquetas, proporción de HS/SS en comentarios y metadatos (identificador, institución, área de estudio, nivel de estudios).
Para responder a las preguntas de investigación, se prevén los siguientes análisis: - Análisis de la varianza, considerando la calificación y la proporción de HS/SS, siendo el cuartil de calificación y los metadatos utilizados como variables de agrupación.
Correlación entre proporción HS/SS y calificación.
Regresión lineal múltiple (variable dependiente: calificación; variables independientes: proporciones HS y SS).
Una parte importante de este trabajo es la preparación de los datos para su posterior utilización. Esta parte se aborda en esta sección. El objetivo principal es compartir el código. Si su interés es ver los dataset terminados, diríjase a la seccion Datos preparados
Cargamos los paquetes de R que vamos a utilizar
library(tidyverse)
library(stringr)
library(tidytext)
library(widyr)
library(ggwordcloud)
library(tm)
library(ggcorrplot)
Cargamos los datos descargados mediante Web Scraper Dev. Se extrajeron de la página https://uruguay.misprofesores.com/Universidades También cargamos los diccionarios que vamos a utilizar.
uruguay <- read.csv("~/R/uruguay2.csv", header = TRUE, sep = ",", dec = ".", comment.char = "", strip.white = TRUE, stringsAsFactors = FALSE, encoding="UTF-8")
instituciones_limpias <- read.csv("~/R/institucionesdeluruguaylexico.csv", header = TRUE, sep = ",", dec = ".", comment.char = "", strip.white = TRUE, stringsAsFactors = FALSE, encoding="UTF-8")
lexico_de_etiquetas <- read.csv("~/R/lexico_de_etiquetas2.csv", header = TRUE, sep = ",", dec = ".", comment.char = "", strip.white = TRUE, stringsAsFactors = FALSE, encoding="UTF-8")
diccionario_de_comentarios <- read.csv("~/R/diccionario_de_comentarios.csv", header = TRUE, sep = ",", dec = ".", comment.char = "", strip.white = TRUE, stringsAsFactors = FALSE, encoding="UTF-8")
Se prepara la base de datos: se borran datos inútiles, se pasa desde un formato long a un formato wide, se combinan etiquetas y comentarios en dos columnas únicas, se eliminan profesores con calificación pero sin etiquetas o comentarios.
profes_sucios <- uruguay %>%
select(etiquetas, nombre, calificacion, Departamento.facultad, comentario, puntuacion.individual, institucionLink) %>%
mutate(nombre= tolower(nombre), etiquetas = removeNumbers(removePunctuation(tolower(etiquetas)))) %>%
mutate(etiquetas= str_replace_all(etiquetas," ", ""), Departamento.facultad = str_replace_all(Departamento.facultad,"Departamento/Facultad:", "")) %>%
mutate(nombre= tolower(nombre), comentario = removeNumbers(removePunctuation(tolower(comentario))), comentario = str_replace_all(comentario, "comentario esperando revisión", ""))
#Se le da formato wide y se crean las "nuevas" variables
profes_limpios <- reshape( within(profes_sucios, q <- ave(seq_along(nombre), nombre, FUN = seq_along)),
direction = "wide",
idvar = "nombre",
timevar = "q") %>%
mutate(etiquetas = paste(etiquetas.1,
"-" ,etiquetas.2, "-" ,etiquetas.3, "-" ,etiquetas.4, "-" ,etiquetas.5,
"-" ,etiquetas.6, "-" ,etiquetas.7, "-" ,etiquetas.8, "-" ,etiquetas.9,
"-" ,etiquetas.10, "-" ,etiquetas.11, "-" ,etiquetas.12, "-" ,etiquetas.13,
"-" ,etiquetas.14, "-" ,etiquetas.15, "-" ,etiquetas.16, "-" ,etiquetas.17,
"-" ,etiquetas.18, "-" ,etiquetas.19, "-" ,etiquetas.20, "-" ,etiquetas.21,
"-" ,etiquetas.22, "-" ,etiquetas.23, "-" ,etiquetas.24, "-" ,etiquetas.25,
"-" ,etiquetas.26, "-" ,etiquetas.27, "-" ,etiquetas.28, "-" ,etiquetas.29,
"-" ,etiquetas.30, "-" ,etiquetas.31, "-" ,etiquetas.32, "-" ,etiquetas.33,
"-" ,etiquetas.34, "-" ,etiquetas.35, "-" ,etiquetas.36, "-" ,etiquetas.37,
"-" ,etiquetas.38, "-" ,etiquetas.39, "-" ,etiquetas.40, "-" ,etiquetas.41,
"-" ,etiquetas.42, "-" ,etiquetas.43, "-" ,etiquetas.44, "-" ,etiquetas.45,
"-" ,etiquetas.46, "-" ,etiquetas.47, "-" ,etiquetas.48, "-" ,etiquetas.49,
"-" ,etiquetas.50, "-" ,etiquetas.51, "-" ,etiquetas.52, "-" ,etiquetas.53,
"-" ,etiquetas.54, "-" ,etiquetas.55, "-" ,etiquetas.56, "-" ,etiquetas.57,
"-" ,etiquetas.58, "-" ,etiquetas.59, "-" ,etiquetas.60, "-" ,etiquetas.61,
"-" ,etiquetas.62, "-" ,etiquetas.63, "-" ,etiquetas.64, "-" ,etiquetas.65,
"-" ,etiquetas.66, "-" ,etiquetas.67, "-" ,etiquetas.68, "-" ,etiquetas.69,
"-" ,etiquetas.70, "-" ,etiquetas.71, "-" ,etiquetas.72, "-" ,etiquetas.73,
"-" ,etiquetas.74, "-" ,etiquetas.75, "-" ,etiquetas.76, "-" ,etiquetas.77,
"-" ,etiquetas.78, "-" ,etiquetas.79, "-" ,etiquetas.80, "-" ,etiquetas.81,
"-", etiquetas.82, "-", etiquetas.83, "-",etiquetas.84,"-", etiquetas.85,"-",
etiquetas.86,"-", etiquetas.87,"-", etiquetas.88,"-", etiquetas.89),
comentarios = paste(comentario.1, "-" ,comentario.2, "-" ,comentario.3, "-" ,comentario.4, "-" ,
comentario.5, "-" ,comentario.6, "-" ,comentario.7, "-" ,comentario.8, "-" ,
comentario.9, "-" ,comentario.10, "-" ,comentario.11, "-" ,comentario.12,
"-" ,comentario.13, "-" ,comentario.14, "-" ,comentario.15, "-" ,comentario.16,
"-" ,comentario.17, "-" ,comentario.18, "-" ,comentario.19, "-" ,comentario.20,
"-" ,comentario.21, "-" ,comentario.22, "-" ,comentario.23, "-" ,comentario.24,
"-" ,comentario.25, "-" ,comentario.26, "-" ,comentario.27, "-" ,comentario.28,
"-" ,comentario.29, "-" ,comentario.30, "-" ,comentario.31, "-" ,comentario.32,
"-" ,comentario.33, "-" ,comentario.34, "-" ,comentario.35, "-" ,comentario.36,
"-" ,comentario.37, "-" ,comentario.38, "-" ,comentario.39, "-" ,comentario.40,
"-" ,comentario.41, "-" ,comentario.42, "-" ,comentario.43, "-" ,comentario.44,
"-" ,comentario.45, "-" ,comentario.46, "-" ,comentario.47, "-" ,comentario.48,
"-" ,comentario.49, "-" ,comentario.50, "-" ,comentario.51, "-" ,comentario.52,
"-" ,comentario.53, "-" ,comentario.54, "-" ,comentario.55, "-" ,comentario.56,
"-" ,comentario.57, "-" ,comentario.58, "-" ,comentario.59, "-" ,comentario.60,
"-" ,comentario.61, "-" ,comentario.62, "-" ,comentario.63, "-" ,comentario.64,
"-" ,comentario.65, "-" ,comentario.66, "-" ,comentario.67, "-" ,comentario.68,
"-" ,comentario.69, "-" ,comentario.70, "-" ,comentario.71, "-" ,comentario.72,
"-" ,comentario.73, "-" ,comentario.74, "-" ,comentario.75, "-" ,comentario.76,
"-" ,comentario.77, "-" ,comentario.78, "-" ,comentario.79, "-" ,comentario.80,
"-" ,comentario.81, "-" ,comentario.82, "-", comentario.83, "-", comentario.84,
"-",comentario.85, "-", comentario.86, "-", comentario.87, "-",
comentario.88, "-", comentario.89)) %>%
mutate(etiquetas= str_replace_all(etiquetas,"NA", ""),
comentario = str_replace_all(comentarios,"NA", "")) %>%
select(nombre, calificacion.1, etiquetas, comentario, Departamento.facultad.1, institucionLink.1) %>%
mutate(calificacion.1 = ifelse(calificacion.1 > 10, 10, calificacion.1))
profes_limpios <- profes_limpios %>%
mutate(letras_en_etiquetas = str_count(profes_limpios$etiquetas, pattern = "[a-z]"),
letras_en_comentarios = str_count(profes_limpios$comentario, pattern = "[a-z]"),
letras_en_ambas_categorias = letras_en_etiquetas + letras_en_comentarios) %>%
filter(letras_en_ambas_categorias > 5)
Se crean dos dataset, uno long y otro wide. Se agregan datos importantes, utilizando diccionarios.
profes_limpios <- profes_limpios %>% inner_join(instituciones_limpias) %>% filter(niveleducativo != "BASURA")
#Se aplica el léxico y se crea un dataset en formato long, centrado en etiquetas
profes_etiquetas_long <- profes_limpios %>% unnest_tokens(word, etiquetas, to_lower = TRUE) %>% inner_join(lexico_de_etiquetas)
# Se crea un dataset en formato wide, que contenga la proporción de etiquetas pedagógicas/personales/generales/institucionales, positivas/negativas/ambivalentes y técnicas/blandas/amplias/NC
#Ámbito
profes_etiquetas_wide2 <- profes_limpios %>% unnest_tokens(word, etiquetas, to_lower = TRUE) %>% inner_join(lexico_de_etiquetas) %>%
group_by(nombre) %>%
count(ambito, nombre, calificacion.1, comentario, institucion, letras_en_etiquetas, letras_en_comentarios, letras_en_ambas_categorias, niveleducativo, area) %>%
spread(ambito, n) %>%
mutate(Pedagógico = ifelse(is.na(Pedagógico), 0, Pedagógico),
Personal = ifelse(is.na(Personal), 0, Personal),
Institucional = ifelse(is.na(Institucional), 0, Institucional),
General = ifelse(is.na(General), 0, General)) %>%
mutate(etiquetas_escritas = sum(Pedagógico, Personal, Institucional, General), Pedagógico = Pedagógico/etiquetas_escritas, Personal = Personal/etiquetas_escritas, Institucional = Institucional/etiquetas_escritas)
#Valencias
profes_etiquetas_wide3 <- profes_limpios %>% unnest_tokens(word, etiquetas, to_lower = TRUE) %>% inner_join(lexico_de_etiquetas) %>%
group_by(nombre) %>%
count(valencia, nombre, calificacion.1, comentario, institucion, letras_en_etiquetas, letras_en_comentarios, letras_en_ambas_categorias, niveleducativo, area) %>%
spread(valencia, n) %>%
mutate(negativa = ifelse(is.na(negativa), 0, negativa),
ambivalente = ifelse(is.na(ambivalente), 0, ambivalente),
positiva = ifelse(is.na(positiva), 0, positiva)) %>%
mutate(valencias_escritas = sum(negativa, ambivalente, positiva), positiva = positiva/valencias_escritas, negativa = negativa/valencias_escritas, ambivalente = ambivalente/valencias_escritas) %>% select(nombre, negativa, ambivalente, positiva)
#Habilidad
profes_etiquetas_wide4 <- profes_limpios %>% unnest_tokens(word, etiquetas, to_lower = TRUE) %>% inner_join(lexico_de_etiquetas) %>%
group_by(nombre) %>%
count(habilidad, nombre, calificacion.1, comentario, institucion, letras_en_etiquetas, letras_en_comentarios, letras_en_ambas_categorias, niveleducativo, area) %>%
spread(habilidad, n) %>%
mutate(técnica_negativa = ifelse(is.na(técnica_negativa), 0, técnica_negativa),
blanda_negativa = ifelse(is.na(blanda_negativa), 0, blanda_negativa),
técnica_positiva = ifelse(is.na(técnica_positiva), 0, técnica_positiva),
blanda_positiva = ifelse(is.na(blanda_positiva), 0, blanda_positiva),
NC = ifelse(is.na(NC), 0, NC)) %>%
mutate(etiquetas_escritas = sum(técnica_negativa, blanda_negativa, técnica_positiva, blanda_positiva, NC),
técnica_negativa = técnica_negativa/etiquetas_escritas,
blanda_negativa = blanda_negativa/etiquetas_escritas,
técnica_positiva = técnica_positiva/etiquetas_escritas,
blanda_positiva = blanda_positiva/etiquetas_escritas,
NC = NC/etiquetas_escritas) %>%
select(nombre, técnica_negativa, blanda_negativa, técnica_positiva, blanda_positiva, NC)
#Se combinan
profes_etiquetados_limpios <- profes_etiquetas_wide2 %>% inner_join(profes_etiquetas_wide3) %>% inner_join(profes_etiquetas_wide4) %>% ungroup() %>% drop_na(blanda_negativa)
Se preparan los comentarios para trabajar con unigramas sin perdida de mucho contenido semántico. Se exploran n-gramas y se transforman los más comunes en unigramas eliminando los espacios entre palabras.
#Se exploran bigramas y manualmente se transforman los más comunes con significado en unigramas. Se presenta el código de la exploración en aras de la transparencia.
#¿cuáles son los bigramas más comunes?
#bigramas <- profes_limpios %>%
# unnest_tokens(bigram, comentario, token = "ngrams", n = 2) %>%
# separate(bigram, c("word1", "word2"), sep = " ") %>%
#count(word1, word2, nombre, sort = TRUE) %>% filter(word1 == "poco") %>%
# unite(word, word1, word2, sep = " ") %>% count(word) %>% arrange(desc(n))
#view(bigramas)
#¿cuáles son los trigramas más comunes?
#trigramas <- profes_limpios %>%
# unnest_tokens(trigram, comentario, token = "ngrams", n = 3) %>%
# separate(trigram, c("word1", "word2", "word3"), sep = " ") %>%
# count(word1, word2, word3, nombre, sort = TRUE) %>% filter(word1 == "no", word2 == "sabe")) %>%
# unite(word, word1, word2, word3, sep = " ") %>% count(word) %>% arrange(desc(n))
#view(trigramas)
#¿Cuáles son los cuatrigramas más comunes?
#cuatrigramas <- profes_limpios %>%
# unnest_tokens(cuatrigram, comentario, token = "ngrams", n = 4) %>%
# separate(cuatrigram, c("word1", "word2", "word3", "word4"), sep = " ") %>%
# count(word1, word2, word3, word4, nombre, sort = TRUE) %>%
# unite(word, word1, word2, word3, word4, sep = " ") %>% count(word) %>% arrange(desc(n))
#basados en los n-gramas más comunes se crean algunos unigramas para facilitar el análisis como unigrama sin perder gran cosa (código muy poco elegante pero que funciona)
profes_limpios <- profes_limpios %>% mutate(comentario = str_replace_all(comentario, "muy buena", "muybuena")) %>%
mutate(comentario = str_replace_all(comentario, "sabe poco", "sabepoco") ) %>%
mutate(comentario = str_replace_all(comentario, "no explica", "noexplica") ) %>%
mutate(comentario = str_replace_all(comentario, "no enseña", "noenseña") ) %>%
mutate(comentario = str_replace_all(comentario, "no ayuda", "noayuda") ) %>%
mutate(comentario = str_replace_all(comentario, "no entiendo", "noentiendo") ) %>%
mutate(comentario = str_replace_all(comentario, "no se entiende", "noseentiende") ) %>%
mutate(comentario = str_replace_all(comentario, "no seleentiende", "noseentiende") ) %>%
mutate(comentario = str_replace_all(comentario, "no entendes", "noentendes") ) %>%
mutate(comentario = str_replace_all(comentario, "no aprendes", "noaprendes") ) %>%
mutate(comentario = str_replace_all(comentario, "no brinda", "nobrinda") ) %>%
mutate(comentario = str_replace_all(comentario, "no respeta", "norespeta") ) %>%
mutate(comentario = str_replace_all(comentario, "no corrige", "nocorrige") ) %>%
mutate(comentario = str_replace_all(comentario, "no responde", "noresponde") ) %>%
mutate(comentario = str_replace_all(comentario, "no recomendable", "norecomendable") ) %>%
mutate(comentario = str_replace_all(comentario, "no aprendí", "noaprendí") ) %>%
mutate(comentario = str_replace_all(comentario, "no acepta", "noacepta") ) %>%
mutate(comentario = str_replace_all(comentario, "no aporta", "noaporta") ) %>%
mutate(comentario = str_replace_all(comentario, "no prepara las clases", "nopreparalasclases") ) %>%
mutate(comentario = str_replace_all(comentario, "no entendés", "noentendés") ) %>%
mutate(comentario = str_replace_all(comentario, "no falta", "nofalta") ) %>%
mutate(comentario = str_replace_all(comentario, "no motiva", "nomotiva") ) %>%
mutate(comentario = str_replace_all(comentario, "no cumple", "nocumple") ) %>%
mutate(comentario = str_replace_all(comentario, "no explica con claridad", "noexplicaconclaridad") ) %>%
mutate(comentario = str_replace_all(comentario, "no entiendes", "noentiendes") ) %>%
mutate(comentario = str_replace_all(comentario, "no escucha", "noescucha") ) %>%
mutate(comentario = str_replace_all(comentario, "nada recomendable", "nadarecomendable") ) %>%
mutate(comentario = str_replace_all(comentario, "nada claro", "nadaclaro") ) %>%
mutate(comentario = str_replace_all(comentario, "nada clara", "nadaclara") ) %>%
mutate(comentario = str_replace_all(comentario, "poco clara", "pococlara") ) %>%
mutate(comentario = str_replace_all(comentario, "poco claras", "pococlara") ) %>%
mutate(comentario = str_replace_all(comentario, "poco claro", "pococlaro") ) %>%
mutate(comentario = str_replace_all(comentario, "poco profesional", "pocoprofesional") ) %>%
mutate(comentario = str_replace_all(comentario, "poco contenido", "pococontenido") ) %>%
mutate(comentario = str_replace_all(comentario, "poco compromiso", "pococompromiso") ) %>%
mutate(comentario = str_replace_all(comentario, "poco comprensible", "pococomprensible") ) %>%
mutate(comentario = str_replace_all(comentario, "sabe algo", "sabealgo") ) %>%
mutate(comentario = str_replace_all(comentario, "sabe menos", "sabemenos") ) %>%
mutate(comentario = str_replace_all(comentario, "excelente docente", "excelentedocente") ) %>%
mutate(comentario = str_replace_all(comentario, "sabe vincularse", "sabevincularse") ) %>%
mutate(comentario = str_replace_all(comentario, "no sabevincularse", "nosabevincularse") ) %>%
mutate(comentario = str_replace_all(comentario, "muy buen", "muybuen") ) %>%
mutate(comentario = str_replace_all(comentario, "excelente profesor", "excelenteprofesor") ) %>%
mutate(comentario = str_replace_all(comentario, "sabe pero", "sabepero") ) %>%
mutate(comentario = str_replace_all(comentario, "buena docente", "buenadocente") ) %>%
mutate(comentario = str_replace_all(comentario, "buen docente", "buendocente") ) %>%
mutate(comentario = str_replace_all(comentario, "buena profesora", "buenaprofesora") ) %>%
mutate(comentario =str_replace_all(comentario, "excelente profesora", "excelenteprofesora") ) %>%
mutate(comentario = str_replace_all(comentario, "sabe mucho", "sabemucho") ) %>%
mutate(comentario = str_replace_all(comentario, "no sabe", "nosabe") ) %>%
mutate(comentario = str_replace_all(comentario, "sabe nada", "sabenada") ) %>%
mutate(comentario =str_replace_all(comentario, "se preocupa", "sepreocupa") ) %>%
mutate(comentario = str_replace_all(comentario, "buena persona", "buenapersona") ) %>%
mutate(comentario =str_replace_all(comentario, "mala persona", "malapersona") ) %>%
mutate(comentario =str_replace_all(comentario, "explica bien", "explicabien") ) %>%
mutate(comentario =str_replace_all(comentario, "buena onda", "buenaonda") ) %>%
mutate(comentario =str_replace_all(comentario, "excelente persona", "excelentepersona") ) %>%
mutate(comentario =str_replace_all(comentario, "buena gente", "buenagente") ) %>%
mutate(comentario =str_replace_all(comentario, "sabe muchísimo", "sabemuchísimo") ) %>%
mutate(comentario =str_replace_all(comentario, "siempre dispuesto", "siempredispuesto") ) %>%
mutate(comentario =str_replace_all(comentario, "excelente profe", "excelenteprofe") ) %>%
mutate(comentario =str_replace_all(comentario, "mala docente", "maladocente") ) %>%
mutate(comentario =str_replace_all(comentario, "no recomiendo", "norecomiendo") ) %>%
mutate(comentario =str_replace_all(comentario, "no lo recomiendo", "nolorecomiendo") ) %>%
mutate(comentario = str_replace_all(comentario, "sabe explicar", "sabeexplicar") ) %>%
mutate(comentario = str_replace_all(comentario, "pro estudiante", "proestudiante") ) %>%
mutate(comentario = str_replace_all(comentario, "llega tarde", "llegatarde")) %>%
mutate(comentario = str_replace_all(comentario, "explica muy bien", "explicabien")) %>%
mutate(comentario = str_replace_all(comentario, "por las ramas", "porlasramas")) %>%
mutate(comentario = str_replace_all(comentario, "se le entiende", "seleentiende")) %>%
mutate(comentario = str_replace_all(comentario, "no se le entiende", "noseleentiende"))%>%
mutate(comentario = str_replace_all(comentario, "clases son claras", "clasesclaras")) %>%
mutate(comentario = str_replace_all(comentario, "es muy exigente", "muyexigente")) %>%
mutate(comentario = str_replace_all(comentario, "explica con claridad", "explicaconclaridad")) %>%
mutate(comentario = str_replace_all(comentario, "se aprende mucho", "se aprende mucho")) %>%
mutate(comentario = str_replace_all(comentario, "se burla", "seburla")) %>%
mutate(comentario = str_replace_all(comentario, "prepara las clases", "preparalasclases")) %>%
mutate(comentario = str_replace_all(comentario, "no prepara las clases", "nopreparalasclases")) %>%
mutate(comentario = str_replace_all(comentario, "clara al explicar", "claraalexplicar"))%>%
mutate(comentario = str_replace_all(comentario, "claro al explicar", "claroalexplicar")) %>%
mutate(comentario = str_replace_all(comentario, "explica muy claro", "explicamuyclaro")) %>%
mutate(comentario = str_replace_all(comentario, "enseñamuybien", "enseñamuybien"))%>%
mutate(comentario = str_replace_all(comentario, "parciales son accesibles", "parcialesaccesibles")) %>%
mutate(comentario = str_replace_all(comentario, "clases son muy claras", "clasesclaras")) %>%
mutate(comentario = str_replace_all(comentario, "responde todas las dudas", "respondelasdudas")) %>%
mutate(comentario = str_replace_all(comentario, "falta de respeto", "faltaderespeto")) %>%
mutate(comentario = str_replace_all(comentario, "se toma el tiempo", "setomatiempo"))%>%
mutate(comentario = str_replace_all(comentario, "falta el respeto", "faltaelrespeto")) %>%
mutate(comentario = str_replace_all(comentario, "hablando de su vida", "hablandodesuvida")) %>%
mutate(comentario = str_replace_all(comentario, "sus clases son dinámicas", "clasesdinamicas")) %>%
mutate(comentario = str_replace_all(comentario, "sus clases son entretenidas", "clasesentretenidas")) %>%
mutate(comentario = str_replace_all(comentario, "clases son muy aburridas", "clasesaburridas")) %>%
mutate(comentario = str_replace_all(comentario, "clases son muy dinámicas", "clasesdinamicas")) %>%
mutate(comentario = str_replace_all(comentario, "clases son muy interesantes", "clasesinteresantes")) %>%
mutate(comentario = str_replace_all(comentario, "comentarios fuera de lugar", "comentariosfueradelugar")) %>%
mutate(comentario = str_replace_all(comentario, "explica de forma clara", "explicadeformaclara")) %>%
mutate(comentario = str_replace_all(comentario, "justa con las notas", "justaconlasnotas")) %>%
mutate(comentario = str_replace_all(comentario, "justo con las notas", "justoconlasnotas")) %>%
mutate(comentario = str_replace_all(comentario, "no es justa con las notas", "injustaconlasnotas")) %>%
mutate(comentario = str_replace_all(comentario, "no es justo con las notas", "injustoconlasnotas"))
Para trabajar con los comentarios, se hace necesario clasificar las palabras. Para ello, se exploran las frecuencias de términos y se crea un diccionario de comentarios. Se clasifican las palabras con frecuencia >5 según el tipo de habilidad (hard, soft) y según su valencia (positiva, negativa y ambivalente); también se incluyen calificadores positivos y negativos (palabras que se refieren a la calidad de la/el docente en general). Se calculan las proporciones de cada grupo de comentarios para cada grupo.
#Versión con todos los datos
profes_comentados_y_etiquetados <- profes_etiquetados_limpios %>% unnest_tokens(word, comentario, to_lower = TRUE) %>%
inner_join(diccionario_de_comentarios) %>%
group_by(nombre) %>%
count(habilidad_y_valencia,
nombre,
calificacion.1,
institucion,
letras_en_comentarios,
niveleducativo,
area,
técnica_positiva,
técnica_negativa,
blanda_positiva,
blanda_negativa) %>%
spread(habilidad_y_valencia, n) %>%
mutate(calificador_negativa = ifelse(is.na(calificador_negativa), 0, calificador_negativa),
calificador_positiva = ifelse(is.na(calificador_positiva), 0, calificador_positiva),
comentario_hard_ambivalente = ifelse(is.na(comentario_hard_ambivalente), 0, comentario_hard_ambivalente),
comentario_hard_negativa = ifelse(is.na(comentario_hard_negativa), 0, comentario_hard_negativa),
comentario_hard_positiva = ifelse(is.na(comentario_hard_positiva), 0, comentario_hard_positiva),
comentario_soft_ambivalente = ifelse(is.na(comentario_soft_ambivalente), 0, comentario_soft_ambivalente),
comentario_soft_positiva = ifelse(is.na(comentario_soft_positiva), 0, comentario_soft_positiva),
comentario_soft_negativa = ifelse(is.na(comentario_soft_negativa), 0, comentario_soft_negativa)) %>%
mutate(habilidades_escritas_en_comentarios = sum(calificador_negativa,
calificador_positiva,
comentario_hard_ambivalente,
comentario_hard_positiva,
comentario_hard_negativa,
comentario_soft_ambivalente,
comentario_soft_positiva,
comentario_soft_negativa),
calificador_positivo_prop = calificador_positiva/habilidades_escritas_en_comentarios,
calificador_negativo_prop = calificador_negativa/habilidades_escritas_en_comentarios,
hard_ambivalente_prop= comentario_hard_ambivalente/habilidades_escritas_en_comentarios,
hard_positiva_prop= comentario_hard_positiva/habilidades_escritas_en_comentarios,
hard_negativa_prop= comentario_hard_negativa/habilidades_escritas_en_comentarios,
soft_ambivalente_prop= comentario_soft_ambivalente/habilidades_escritas_en_comentarios,
soft_positiva_prop= comentario_soft_positiva/habilidades_escritas_en_comentarios,
soft_negativa_prop= comentario_soft_negativa/habilidades_escritas_en_comentarios
)
#Versión para análisis posteriores
profes_comentados_y_etiquetados_limpio <- profes_comentados_y_etiquetados %>%
mutate(calificación = calificacion.1) %>%
select(nombre,
area,habilidades_escritas_en_comentarios,
niveleducativo,
calificación,
técnica_positiva,
técnica_negativa,
blanda_positiva,
blanda_negativa,
calificador_positivo_prop,
calificador_negativo_prop,
hard_ambivalente_prop,
hard_positiva_prop,
hard_negativa_prop,
soft_ambivalente_prop,
soft_positiva_prop,
soft_negativa_prop) %>% ungroup() %>% rename(tec_pos = técnica_positiva,
tec_neg = técnica_negativa,
blan_pos = blanda_positiva,
blan_neg = blanda_negativa,
cali_pos = calificador_positivo_prop,
cali_neg = calificador_negativo_prop,
hard_amb = hard_ambivalente_prop,
hard_pos = hard_positiva_prop,
hard_neg = hard_negativa_prop,
soft_amb = soft_ambivalente_prop,
soft_pos = soft_positiva_prop,
soft_neg = soft_negativa_prop)
Después de este procesamiento, disponemos de cinco datasets ligeramente diferentes y útiles para distintos análisis:
profes_etiquetas_long: una versión en formato long, ideal para trabajar con las etiquetas a nivel cualitativo y cuantitativo. n=3744 sujetos con etiquetas.
profes_etiquetados_limpios: una versión en formato wide con los porcentajes de etiquetas por sujeto. Se eliminan sujetos con información incompleta. n=3685
profes_comentados_y_etiquetados: una versión wide, centrada en los sujetos, restringida a docentes con comentarios y etiquetas, con cálculo de la proporción de cada etiqueta/palabra. n= 3.062
profes_comentados_y_etiquetados_limpio: una versión limpia, identica a la anterior pero incluyendo solo las variables que se utilizarán en análisis posteriores. n= 3.062
profes_limpios: una versión formato wide sin proporciones de etiquetas, con todos los sujetos que tienen al menos una etiqueta o un comentario. n=4477
Versión centrada en las etiquetas. Ideal para análisis de frecuencias de etiquetas por área, institución, etc.
profes_etiquetas_long