Bucles R para la limpieza básica de datos

Soy un poco nuevo en R y en la programación en general. Tengo que limpiar una gran cantidad de datos y, a menudo, es un problema similar en varias columnas. Entonces, me gustaría usar un bucle, en lugar de escribir cada línea de código. Tengo datos similares a este:

black <- c("1.33%", "9.22%", "10.71%")
white <- c("5.23%", "8.12%", "11.72%")
day <- c("Wednesday", "Thursday", "Friday")
blue <- c("2.21%", "1.12%", "8.79%")
df <- data.frame(black, white, day, blue)

Esto me da un marco de datos como este:

   black  white       day  blue
1  1.33%  5.23% Wednesday 2.21%
2  9.22%  8.12%  Thursday 1.12%
3 10.71% 11.72%    Friday 8.79%

He leído que hay bucles 'for', y también que la familia apply() también funciona como bucles en R... ¿Cómo recorrería las variables negro, blanco y azul (pero no el día) para poder:

  • quitar el signo %
  • cambiar el tipo de carácter a numérico
  • redondear a 1 decimal?

Como digo, me gustaría saber cómo escribir esto como un bucle for y aplicar. Para quitar el signo % he usado mutate y gsub antes...

¡Gracias por sus sugerencias, particularmente por ayudarme a escribir código legible! Mejor, roger

Answer

Aquí hay una forma ordenada de usar dplyr

library(dplyr)

clean_my_data<-function(input){
   gsub("%", "", input) %>% as.numeric() %>% round(1)
}

df_new<-df %>%
  mutate(across(c(black,white,blue), clean_my_data))

df_new
#>   black white       day blue
#> 1   1.3   5.2 Wednesday  2.2
#> 2   9.2   8.1  Thursday  1.1
#> 3  10.7  11.7    Friday  8.8

Creado el 2022-01-15 por el paquete reprex (v2.0.1)

¡Esta es una forma rápida y sucia de hacerlo y se puede mejorar!

Primero necesita una función que haga el trabajo, luego aplica esa función (o hace un bucle, depende de usted).

clean_color <- function(x) {
# just remove the last char, it can fail on data like that "1.38% "
    without_percent = substr(x, 
                           start = 1, 
                           stop = nchar(x) - 1)
# second part convert in mun and round it
    round(as.numeric(without_percent),1)
        }

Luego aplicas esta función:

sapply(df[,c(1:2,4)], clean_color)