A menudo trato con datos de encuestas desordenados que requieren mucha limpieza antes de que se puedan realizar estadísticas. Solía hacer esto "manualmente" en Excel, a veces usando fórmulas de Excel, y otras comprobando las entradas una por una. Comencé a hacer cada vez más estas tareas escribiendo guiones para hacerlas en R, lo cual ha sido muy beneficioso (los beneficios incluyen tener un registro de lo que se hizo, menos posibilidades de errores y poder reutilizar el código si el conjunto de datos es actualizado).
Pero todavía hay algunos tipos de datos que tengo problemas para manejar de manera eficiente. Por ejemplo:
> d <- data.frame(subject = c(1,2,3,4,5,6,7,8,9,10,11),
+ hours.per.day = c("1", "2 hours", "2 hr", "2hr", "3 hrs", "1-2", "15 min", "30 mins", "a few hours", "1 hr 30 min", "1 hr/week"))
> d
subject hours.per.day
1 1 1
2 2 2 hours
3 3 2 hr
4 4 2hr
5 5 3 hrs
6 6 1-2
7 7 15 min
8 8 30 mins
9 9 a few hours
10 10 1 hr 30 min
11 11 1 hr/week
hours.per.day
está destinado a ser el número promedio de horas por día dedicadas a una determinada actividad, pero lo que tenemos es exactamente lo que escribió el sujeto. Supongamos que tomo algunas decisiones sobre qué hacer con respuestas ambiguas, y quiero la variable ordenada de la hours.per.day2
siguiente manera.
subject hours.per.day hours.per.day2
1 1 1 1.0000000
2 2 2 hours 2.0000000
3 3 2 hr 2.0000000
4 4 2hr 2.0000000
5 5 3 hrs 3.0000000
6 6 1-2 1.5000000
7 7 15 min 0.2500000
8 8 30 mins 0.5000000
9 9 a few hours 3.0000000
10 10 1 hr 30 min 1.5000000
11 11 1 hr/week 0.1428571
Suponiendo que el número de casos es bastante grande (digamos 1000) y sabiendo que los sujetos eran libres de escribir lo que quisieran, ¿cuál es la mejor manera de abordar esto?
fuente
new_var[by.hand] <- c(2, 1, ...)
conby.hand
estarTRUE
en los casos que se hacen a mano?XML
para ayudarlo a extraer datos, pero esto no funciona cuando el HTML está mal formado.)La sugerencia de @ Max es buena. Parece que si escribe un algoritmo que reconoce números, así como palabras / abreviaturas comunes asociadas con el tiempo, obtendrá la mayor parte del camino. Este no será un código hermoso, pero funcionará y puede mejorarlo con el tiempo a medida que se encuentre con casos problemáticos.
Pero para un enfoque más robusto (y que inicialmente consume mucho tiempo), intente buscar en Google "analizando una cadena de tiempo de lenguaje natural". Algunos hallazgos interesantes son esta API de tiempo abierto , un buen módulo de Python y uno de los muchos hilos relacionados como este en Stack Overflow .
Básicamente, el análisis del lenguaje natural es un problema común y debe buscar soluciones en otros idiomas además de R. Puede crear herramientas en otro idioma al que pueda acceder utilizando R, o al menos puede obtener buenas ideas para su propio algoritmo.
fuente
Para algo así, si fuera lo suficientemente largo, creo que querría una lista de expresiones regulares y reglas de transformación, y llevar los nuevos valores a otra columna (para que siempre tenga la oportunidad de verificar dos veces sin volver a cargar los datos sin procesar) ; los RE se aplicarían a los datos no tan transformados hasta que se hayan transformado todos los datos o se hayan agotado todas las reglas. Probablemente sea mejor también mantener una lista de valores lógicos que indiquen qué filas aún no se han transformado.
Algunas de esas reglas son obvias, por supuesto, y probablemente manejarán el 80-90% de los casos, pero el problema es que siempre habrá algunas que no sabes que surgirán (las personas son muy ingeniosas).
Luego, necesita una secuencia de comandos que revise y presente los originales de los valores aún no transformados por la lista de reglas obvias de uno en uno, lo que le brinda la oportunidad de hacer una expresión regular (digamos ) para identificar esos casos y dar una nueva transformación para los casos que se ajustan a él, que se agrega a la lista original y se aplica a las filas del vector original que aún no se han transformado antes de verificar si quedan casos para presentarle .
También podría ser razonable tener la opción de omitir un caso (para poder pasar a otros más fáciles), de modo que pueda llevar los casos muy difíciles hasta el final.
En el peor de los casos, haces algunos a mano.
Luego puede mantener la lista completa de reglas que genera, para aplicar nuevamente cuando los datos crecen o aparece un nuevo conjunto de datos similar.
No sé si se está acercando remotamente a las mejores prácticas (creo que se necesitaría algo mucho más formal allí), pero en términos de procesar grandes cantidades de dichos datos rápidamente, podría tener algún valor.
fuente
R contiene algunos estándar funciones para la manipulación de datos, que pueden ser utilizados para la limpieza de datos, en su base de paquete (
gsub
,transform
, etc.), así como en varios paquetes de terceros, tales como stringr , reshape , reshape2 , y plyr . En el siguiente documento se describen ejemplos y mejores prácticas de uso de estos paquetes y sus funciones: http://vita.had.co.nz/papers/tidy-data.pdf .Además, R ofrece algunos paquetes específicamente enfocados en la limpieza y transformación de datos:
Un enfoque integral y coherente de datos de limpieza en R, incluyendo ejemplos y el uso de editrules y deducorrect paquetes, así como una descripción de flujo de trabajo ( marco ) de los datos de limpieza en R, se presenta en el siguiente documento, que recomiendo encarecidamente: http : //cran.r-project.org/doc/contrib/de_Jonge+van_der_Loo-Introduction_to_data_cleaning_with_R.pdf .
fuente