Estoy buscando una forma de extraer un modo de colume ("meteo2") por múltiples grupos ("temporada", "meteo") que tienen formato de factor en mi marco de datos, "mydf". Aquí está mi código de prueba como se muestra a continuación, pero que no funciona, lo que genera un mensaje de error. Con un grupo, "temporada", funciona. Tres columnas tienen todos los valores "NA". No estoy seguro de qué parte está mal en mi código. Cualquier ayuda es muy bienvenida!

str(mydf$season)
Factor w/ 4 levels "Spring","Summer",...:
 str(mydf$meteo)
Factor w/ 7 levels "<40","<50","<60",..: 
str(mydf$meteo2)
Factor w/ 4 levels "E","N","S","W": 

# mode function
Mode = function(x){ 
ta = table(x)
tam = max(ta)
if (all(ta == tam))
     mod = NA
else
     if(is.numeric(x))
mod = as.numeric(names(ta)[ta == tam])
else
     mod = names(ta)[ta == tam]
return(mod)}

# extracting mode
dataSummary<-mydf %>% select(season, meteo, meteo2) %>%
mutate(meteo = forcats::fct_explicit_na(meteo)) %>%
group_by(meteo, season) %>%
summarise(m=Mode(meteo2))

dataSummary
error : Column `m` can't promote group 30 to character

Aquí están mis datos de muestra.

dput(head(mydf_sample))
structure(list(season = structure(c(3L, 3L, 3L, 3L, 3L, 3L), .Label = c("Spring", 
"Summer", "Fall", "Winter"), class = "factor"), meteo2 = structure(c(2L, 
2L, 2L, 1L, 2L, 2L), .Label = c("E", "N", "S", "W"), class = "factor"), 
    meteo = structure(c(6L, 6L, 6L, 6L, 7L, 7L), .Label = c("<40", 
    "<50", "<60", "<70", "<75", "<80", "80+"), class = "factor")), .Names = c("season", 
"meteo2", "meteo"), row.names = c(NA, 6L), class = "data.frame")
> 

0
user2928318 14 abr. 2020 a las 08:31

2 respuestas

La mejor respuesta

Su error no se reprodujo con los datos de muestra.

Pero si su objetivo es producir el modo, esto es posible más directamente contando las combinaciones y tomando la más común.

mydf %>%
  mutate(meteo = forcats::fct_explicit_na(meteo)) %>%
  count(meteo, season, meteo2) %>%
  arrange(desc(n)) %>%
  distinct(meteo, season, .keep_all = TRUE) %>%
  select(-n)

Llamar a distinct tomará la primera opción que vea, que es la más común debido a que orden descendente de organizar.

Eso solo elegirá una de las opciones en caso de empate. Si eso le preocupa, puede seleccionar todo con un poco de ajuste.

mydf %>%
  mutate(meteo = forcats::fct_explicit_na(meteo)) %>%
  count(meteo, season, meteo2) %>%
  group_by(meteo, season) %>%
  filter(n == max(n)) %>%
  ungroup() %>%
  select(-n)
1
mcskinner 14 abr. 2020 a las 07:05

Desde el mensaje de error, parece que algunos grupos no devuelven valores de caracteres (probablemente NA que es de clase lógica). Puede convertirlos explícitamente en caracteres utilizando as.character.

library(dplyr)

mydf_sample %>% group_by(meteo,season) %>% summarise(m=as.character(Mode(meteo2)))
1
Ronak Shah 14 abr. 2020 a las 07:16