Convertir los números de caracteres a numéricos en una lista anidada con tipos mixtos en R.
Tengo un montón de listas anidadas que llegan con todos sus elementos de tipo carácter. Algunos de estos caracteres son en realidad números que necesitan ser convertidos a elementos de tipo numérico.
¿Cómo puedo modificar estas listas para que todos los números de tipo carácter posibles se conviertan en numéricos, pero los elementos de tipo carácter no numéricos permanezcan intactos (es decir, no se conviertan en NA mediante as.numeric())?
Por ejemplo, comienzo con
raw_list <- list(
'a' = list('1', '2'),
'b' = list(
'c' = list('3', 'x'),
'd' = c('4', 'z'),
'e' = '5'))
Pero necesito obtener
cleaned_list <- list(
'a' = list(1, 2),
'b' = list(
'c' = list(3, 'x'),
'd' = c('4', 'z'),
'e' = 5))
Bono: Extra gratitud por soluciones basadas en tidyverse/purrr.
davy.ai
Una forma de lograr esto es utilizando el paquete
purrr
y la funciónmap()
para iterar sobre las listas anidadas y aplicar la funciónas.numeric()
a cualquier elemento de tipo caracter que pueda convertirse en número. Aquí tienes un ejemplo de código:Este código primero itera sobre la lista más externa utilizando
map()
, y luego aplica la funciónmap_if()
a cada elemento para verificar si es un vector de caracteres (is.character()
). Si lo es, aplica la funciónsafely()
a él, que intenta convertirlo a numérico pero no genera un error si falla. Esto se debe a que algunos vectores de caracteres pueden contener texto no numérico (como “x” y “z” en el ejemplo), y queremos mantenerlos tal cual.El argumento
.else = identity
enmap_if()
significa que si no se cumple la condición (es decir, el elemento no es un vector de caracteres), se devuelve el elemento sin cambios (identity
).La función
flatten()
se utiliza para eliminar un nivel de anidación de la lista resultante, de modo que obtengamos una lista de vectores en lugar de una lista de listas.Finalmente, se aplica nuevamente
map_if()
para reemplazar los elementos numéricos infinitos porNA
utilizando la funciónna_if()
. Si no quieres reemplazar los valores infinitos, puedes omitir estas líneas.La lista resultante
clean_list
debería tener la misma estructura queraw_list
, pero con todos los elementos de tipo caracter que se puedan convertir a números reemplazados por elementos numéricos.