convertir columnas de lista de marco de datos a factor

Oct 09 2020

Hola, le estoy dando etiquetas a mi marco de datos manualmente como se muestra a continuación, tengo 800 columnas para etiquetar, después de eso estoy creando un subconjunto de marco de datos (la configuración secundaria de datos tiene muchos), luego aplicando ese marco de datos para funcionar para el cálculo.

las etiquetas pueden ser diferentes para todos los fragmentos, y también es necesario mucho tiempo para crear etiquetas una por una para todos los fragmentos.

data<-data.frame( col1=c(1,1,NA,NA,NA,NA,NA,NA,1,NA,NA,NA,NA,NA,NA,NA,NA,1,NA,NA,NA,1,1,1,NA,1,1,NA,NA,NA,NA,1,NA,NA,NA,NA,1,NA,1),
                  col2=c(1,1,1,1,1,NA,NA,NA,NA,1,1,1,1,1,NA,NA,NA,1,1,1,NA,1,1,1,1,1,NA,NA,NA,1,1,1,1,1,1,1,NA,NA,NA),
                  col3=c(1,1,NA,NA,NA,NA,NA,1,NA,NA,NA,NA,NA,NA,NA,NA,1,NA,NA,NA,NA,NA,1,1,1,NA,NA,NA,1,NA,NA,1,1,1,1,1,NA,NA,1),
                  col4=c(1,NA,NA,NA,NA,NA,NA,NA,NA,NA,1,NA,NA,NA,NA,NA,NA,NA,1,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA),
                  col5=c(1,2,1,1,1,2,1,2,2,1,2,NA,1,1,2,2,2,1,1,1,2,NA,2,1,1,1,2,2,2,NA,1,2,2,1,1,1,2,2,2)
)  

data$col5<-factor(data$col5, levels=c(1,2), labels=c("Local","Overseas"))

df<- data
df$cc1<-1 df2<- subset(df, col5 == 'Local') df$cc2<-ifelse(df$col5 == 'Local',1,NA) lst<-list(df$cc1, df$cc2)
ldat<-list("ALL" = df, "Local" =df2)

col_names <- c("col1","col2"...."col4")
    labels <- c("Sales","Ops"...."HR")

make_mutator <- function(x) {
  paste0(
    "factor(", names(faclist)[[x]],
    ",labels=c('",
    paste0(faclist[[x]],
           collapse = "','"
    ), "'))"
  )
}


list_of_fac <- purrr::map_chr(seq_len(length(faclist)),
                              make_mutator)

names(list_of_fac) <- names(faclist)

ldat <- purrr::map(ldat,
                   ~mutate(.,
                           !!!parse_exprs(list_of_fac)))

Esto está perfectamente bien y funciona para mí ... pero solo quiero una nueva solución si le doy columnas y etiquetas por separado para columnas y etiquetas como

nombres_col <- c ("col1", "col2" .... "col4") etiquetas <- c ("Ventas", "Ops" .... "HR")

entonces, ¿cómo puedo cambiar mi función para esto .... ??

Respuestas

2 akrun Oct 09 2020 at 12:41

En lugar del análisis sintáctico, una opción más fácil es usarla map2después de recorrer el listcon map. Con map2, pasamos las columnas de interés y las etiquetas a cambiar en función del list'faclist' denominado

library(dplyr)
library(purrr)
ldat1 <- map(ldat, ~  {
     .x[names(faclist)] <- map2(.x %>% 
                             dplyr::select(names(faclist)), 
                         faclist, ~ factor(.x, labels= .y))
       .x} )

-salida

str(ldat1[[1]])
#'data.frame':  39 obs. of  7 variables:
# $ col1: Factor w/ 1 level "Sales": 1 1 NA NA NA NA NA NA 1 NA ... # $ col2: Factor w/ 1 level "OPS": 1 1 1 1 1 NA NA NA NA 1 ...
# $ col3: Factor w/ 1 level "Management": 1 1 NA NA NA NA NA 1 NA NA ... # $ col4: Factor w/ 1 level "HR": 1 NA NA NA NA NA NA NA NA NA ...
# $ col5: Factor w/ 2 levels "Local","Overseas": 1 2 1 1 1 2 1 2 2 1 ... # $ cc1 : num  1 1 1 1 1 1 1 1 1 1 ...
# $ cc2 : num 1 NA 1 1 1 NA 1 NA NA 1 ... str(ldat1[[2]]) #'data.frame': 18 obs. of 6 variables: # $ col1: Factor w/ 1 level "Sales": 1 NA NA NA NA NA NA NA 1 NA ...
#$ col2: Factor w/ 1 level "OPS": 1 1 1 1 NA 1 1 1 1 1 ... # $ col3: Factor w/ 1 level "Management": 1 NA NA NA NA NA NA NA NA NA ...
# $ col4: Factor w/ 1 level "HR": 1 NA NA NA NA NA NA NA NA 1 ... # $ col5: Factor w/ 2 levels "Local","Overseas": 1 1 1 1 1 1 1 1 1 1 ...
# $ cc1 : num  1 1 1 1 1 1 1 1 1 1 ...

Si no es un list, sino dos vectores, simplemente cambie el names(faclist)con el vector 'col_names' y el list'faclist' con el labelsvector

ldat1 <- map(ldat, ~  {
     .x[col_names] <- map2(.x %>% 
                             dplyr::select(col_names), 
                         labels, ~ factor(.x, labels= .y))
       .x} )