Larissa Cury
Larissa Cury

Reputation: 858

Unknown levels in `f`:() but the columns are already factors

I've seen many posts concerning the warning Unknown levels in `f`: , however, all of them concerned the fact that the variable wasn't a factor before using fct_collapse(). All my variables are already factors, but I'm getting this warning nevertheless. How can I get rid of Unknown levels in `f`: ?

Data contains number of hours (in Portuguese, I'm sorry) as very big strings. I want to make the strings shorter. Hence, for example 'Mais de 10 horas em língua adicional' (more than 10 hours in additional language) should become '> 10'. That's the idea.

data %>% 
       mutate(across(-SCHOOL, ~ fct_collapse(.,
                                     'Não oferta' = c('Não oferecemos este nível de ensino na escola', 
                                                      'Não oferecemos este nível de ensino bilíngue na escola'), 
                                     '> 20h' = c('Mais de 20 horas/ períodos semanais'),
                                     '> 10h' = c('Mais de 10 horas/ períodos semanais', 
                                                 'Mais de 10 horas em língua adicional'),
                                     '= 20h' = c('20 horas/ períodos semanais'),
                                     'Até 10h' = c('Até 10 horas/períodos semanais'),
                                     '= 1h' = c('1 hora em língua adicional'),
                                     '100% CH' = c('100% da carga-horária em língua adicional'),
                                     '> 15h' = c('Mais de 15 horas/ períodos semanais'),
                                     '> 30h' = c('Mais de 30 horas/ períodos semanais'),
                                     '50% CH' = c('50% da carga- horária em língua adicional',
                                     '= 3h' = c('3 horas em língua adicional'),
                                     '= 6h' = c('6 horas em língua adicional'),
                                     '= 5h' = c('5 horas em língua adicional'),
                                     '= 2h' = c('2 horas em língua adicional'),
                                     '= 10h' = c('10 horas em língua adicional'),
                                     '9h' = c('9 horas em língua adicional'),
                                     '8h' = c('8 horas em língua adicional', 
                                              '8 horas em aíngua adicional'), ## digitação
                                     '3h' = c('3 horas em língua adicional'),
                                     '4h' = c('4 horas em língua adicional'),
                                     '7h' = c('7 horas em língua adicional'),
                                     '2h' = c('2 horas em língua adicional')))))
# Note: I've excluded the ```school``` column to preserve participants' id

dput(my_data)
structure(list(Q21 = structure(c(5L, 5L, 5L, 4L, 3L, 5L, 4L, 
5L, 5L, 5L, 5L, 1L, 2L, 5L, 5L, 5L, 5L, 1L, 5L, 5L, 5L, 5L, 5L, 
5L, 4L, 5L, 5L, 2L, 5L), .Label = c("20 horas/ períodos semanais", 
"Até 10 horas/períodos semanais", "Mais de 10 horas/ períodos semanais", 
"Mais de 20 horas/ períodos semanais", "Não oferecemos este nível de ensino na escola"
), class = "factor"), Q22 = structure(c(1L, 2L, 1L, 4L, 3L, 4L, 
5L, 1L, 6L, 6L, 6L, 1L, 2L, 6L, 6L, 6L, 2L, 1L, 6L, 6L, 6L, 6L, 
3L, 6L, 5L, 2L, 6L, 2L, 5L), .Label = c("20 horas/ períodos semanais", 
"Até 10 horas/períodos semanais", "Mais de 10 horas/ períodos semanais", 
"Mais de 15 horas/ períodos semanais", "Mais de 20 horas/ períodos semanais", 
"Não oferecemos este nível de ensino na escola"), class = "factor"), 
    Q23 = structure(c(4L, 2L, 4L, 4L, 3L, 4L, 5L, 1L, 5L, 5L, 
    1L, 1L, 2L, 6L, 4L, 3L, 2L, 1L, 3L, 6L, 6L, 4L, 3L, 4L, 4L, 
    1L, 1L, 2L, 1L), .Label = c("20 horas/ períodos semanais", 
    "Até 10 horas/períodos semanais", "Mais de 10 horas/ períodos semanais", 
    "Mais de 15 horas/ períodos semanais", "Mais de 20 horas/ períodos semanais", 
    "Não oferecemos este nível de ensino na escola"), class = "factor"), 
    Q24 = structure(c(5L, 3L, 1L, 4L, 3L, 4L, 5L, 4L, 1L, 1L, 
    1L, 1L, 2L, 7L, 4L, 3L, 1L, 1L, 3L, 5L, 2L, 5L, 3L, 5L, 4L, 
    6L, 1L, 4L, 1L), .Label = c("20 horas/ períodos semanais", 
    "Até 10 horas/períodos semanais", "Mais de 10 horas/ períodos semanais", 
    "Mais de 15 horas/ períodos semanais", "Mais de 20 horas/ períodos semanais", 
    "Mais de 30 horas/ períodos semanais", "Não oferecemos este nível de ensino na escola"
    ), class = "factor"), Q25 = structure(c(5L, 3L, 5L, 4L, 4L, 
    4L, 5L, 2L, 1L, 1L, 1L, 1L, 2L, 7L, 4L, 3L, 1L, 1L, 3L, 5L, 
    2L, 5L, 3L, 5L, 4L, 6L, 5L, 4L, 1L), .Label = c("20 horas/ períodos semanais", 
    "Até 10 horas/períodos semanais", "Mais de 10 horas/ períodos semanais", 
    "Mais de 15 horas/ períodos semanais", "Mais de 20 horas/ períodos semanais", 
    "Mais de 30 horas/ períodos semanais", "Não oferecemos este nível de ensino na escola"
    ), class = "factor"), Q26 = structure(c(5L, 7L, 5L, 4L, 4L, 
    4L, 5L, 2L, 5L, 5L, 1L, 1L, 2L, 4L, 5L, 4L, 7L, 7L, 3L, 6L, 
    2L, 5L, 3L, 5L, 1L, 6L, 5L, 4L, 5L), .Label = c("20 horas/ períodos semanais", 
    "Até 10 horas/períodos semanais", "Mais de 10 horas/ períodos semanais", 
    "Mais de 15 horas/ períodos semanais", "Mais de 20 horas/ períodos semanais", 
    "Mais de 30 horas/ períodos semanais", "Não oferecemos este nível de ensino na escola"
    ), class = "factor"), Q27 = structure(c(6L, 7L, 6L, 1L, 4L, 
    4L, 5L, 2L, 6L, 6L, 7L, 5L, 3L, 4L, 5L, 7L, 7L, 7L, 3L, 6L, 
    7L, 7L, 4L, 6L, 7L, 6L, 7L, 5L, 6L), .Label = c("20 horas/ períodos semanais", 
    "Até 10 horas/períodos semanais", "Mais de 10 horas/ períodos semanais", 
    "Mais de 15 horas/ períodos semanais", "Mais de 20 horas/ períodos semanais", 
    "Mais de 30 horas/ períodos semanais", "Não oferecemos este nível de ensino na escola"
    ), class = "factor"), Q28 = structure(c(1L, 1L, 1L, 1L, 7L, 
    5L, 1L, 1L, 1L, 1L, 1L, 1L, 3L, 9L, 1L, 6L, 1L, 4L, 1L, 1L, 
    1L, 1L, 1L, 2L, 1L, 1L, 1L, 8L, 1L), .Label = c("", "1º a 4º ano do Fundamental 1: 27h/aula total, 21h/aula em Língua Portuguesa\n5º ano Fundamental 1: 30h/a total, 24h/a em Língua Portuguesa\n6º ao 8º Fundamental II: 29h/a total, 27h/a em Língua Portuguesa\n9º, Fundamental II: 36h/a total, 34h/a em Língua Portuguesa\n1ª série, EM: ainda em discussão\n2ª série, EM: ainda em discussão\n3ª série, EM: ainda em discussão", 
    "Até 4 anos: 1 aula de cultura brasileira\n5 anos: 5 aulas por semana\n6-10 anos: 7 aulas - sendo 5 portugues, 2 estudos sociais\nAcima: 9 aulas", 
    "Em inglês, L2, oferecemos no EI 22h30 e no EFI 10h semanalmente", 
    "Inglês: Nível 1 e 2 (1 ano a 2 anos) 30min semanais; nível 3, 4 e 5 (3 a 5 anos) 1h20semanal; ensino fundamental 1h30 (semanal) obs. Carga horaria tradicional: 2 encontros de 50min", 
    "Na educação infantil, cerca de 15% do currículo é ministrado em língua portuguesa. No Ensino Fundamental 1, 50% são ministradas em língua portuguesa. No Ensino Fundamental 2, 60% são ministradas em língua portuguesa.", 
    "No ensino médio a prática de Laboratório  de redação é mais latente.", 
    "O aumento da carga horária é gradativa, conforme a idade e os segmentos.", 
    "Temos duas trilhas no Ensino Médio: trilha nacional e a trilha internacional. Na Nacional, os tempos em inglês são reduzidos, do total de 32 aulas de aula (sem contar intervalos e almoço) somente 4 aulas de 1 hora são em inglês. Na trilha internacional, das 32 aulas 14 delas são em língua inglesa. "
    ), class = "factor"), Q29 = structure(c(5L, 5L, 5L, 5L, 5L, 
    1L, 5L, 5L, 5L, 5L, 5L, 5L, 2L, 5L, 5L, 5L, 5L, 3L, 5L, 5L, 
    5L, 5L, 5L, 5L, 5L, 5L, 5L, 4L, 5L), .Label = c("1 hora em língua adicional", 
    "100% da carga-horária em língua adicional", "50% da carga- horária em língua adicional", 
    "Mais de 10 horas em língua adicional", "Não oferecemos este nível de ensino bilíngue na escola"
    ), class = "factor"), Q30 = structure(c(7L, 3L, 5L, 9L, 1L, 
    1L, 9L, 4L, 9L, 9L, 9L, 4L, 2L, 9L, 9L, 9L, 6L, 6L, 9L, 9L, 
    9L, 9L, 2L, 9L, 9L, 4L, 9L, 8L, 1L), .Label = c("1 hora em língua adicional", 
    "10 horas em língua adicional", "100% da carga-horária em língua adicional", 
    "3 horas em língua adicional", "5 horas em língua adicional", 
    "50% da carga- horária em língua adicional", "6 horas em língua adicional", 
    "Mais de 10 horas em língua adicional", "Não oferecemos este nível de ensino bilíngue na escola"
    ), class = "factor"), Q31 = structure(c(10L, 3L, 11L, 10L, 
    12L, 1L, 5L, 5L, 6L, 5L, 7L, 5L, 3L, 13L, 7L, 12L, 8L, 8L, 
    2L, 13L, 2L, 9L, 2L, 9L, 10L, 7L, 4L, 12L, 7L), .Label = c("1 hora em língua adicional", 
    "10 horas em língua adicional", "100% da carga-horária em língua adicional", 
    "2 horas em língua adicional", "3 horas em língua adicional", 
    "4 horas em língua adicional", "5 horas em língua adicional", 
    "50% da carga- horária em língua adicional", "6 horas em língua adicional", 
    "8 horas em aíngua adicional", "9 horas em língua adicional", 
    "Mais de 10 horas em língua adicional", "Não oferecemos este nível de ensino bilíngue na escola"
    ), class = "factor"), Q32 = structure(c(12L, 8L, 2L, 11L, 
    12L, 1L, 6L, 5L, 7L, 7L, 9L, 5L, 3L, 13L, 10L, 8L, 4L, 2L, 
    2L, 11L, 2L, 10L, 2L, 9L, 12L, 7L, 5L, 12L, 7L), .Label = c("1 hora em língua adicional", 
    "10 horas em língua adicional", "100% da carga-horária em língua adicional", 
    "2 horas em língua adicional", "3 horas em língua adicional", 
    "4 horas em língua adicional", "5 horas em língua adicional", 
    "50% da carga- horária em língua adicional", "6 horas em língua adicional", 
    "7 horas em língua adicional", "8 horas em aíngua adicional", 
    "Mais de 10 horas em língua adicional", "Não oferecemos este nível de ensino bilíngue na escola"
    ), class = "factor"), Q33 = structure(c(7L, 8L, 2L, 11L, 
    12L, 1L, 6L, 5L, 7L, 7L, 10L, 5L, 3L, 13L, 10L, 8L, 4L, 2L, 
    2L, 11L, 2L, 10L, 2L, 9L, 12L, 7L, 5L, 12L, 7L), .Label = c("1 hora em língua adicional", 
    "10 horas em língua adicional", "100% da carga-horária em língua adicional", 
    "2 horas em língua adicional", "3 horas em língua adicional", 
    "4 horas em língua adicional", "5 horas em língua adicional", 
    "50% da carga- horária em língua adicional", "6 horas em língua adicional", 
    "7 horas em língua adicional", "8 horas em aíngua adicional", 
    "Mais de 10 horas em língua adicional", "Não oferecemos este nível de ensino bilíngue na escola"
    ), class = "factor"), Q34 = structure(c(7L, 11L, 2L, 5L, 
    2L, 1L, 6L, 4L, 5L, 7L, 8L, 11L, 3L, 10L, 8L, 10L, 11L, 11L, 
    11L, 9L, 8L, 9L, 11L, 11L, 2L, 7L, 5L, 10L, 7L), .Label = c("1 hora em língua adicional", 
    "10 horas em língua adicional", "100% da carga-horária em língua adicional", 
    "2 horas em língua adicional", "3 horas em língua adicional", 
    "4 horas em língua adicional", "5 horas em língua adicional", 
    "7 horas em língua adicional", "8 horas em aíngua adicional", 
    "Mais de 10 horas em língua adicional", "Não oferecemos este nível de ensino bilíngue na escola"
    ), class = "factor"), Q35 = structure(c(5L, 9L, 9L, 4L, 9L, 
    9L, 4L, 3L, 3L, 3L, 9L, 9L, 6L, 8L, 7L, 9L, 9L, 9L, 9L, 9L, 
    9L, 9L, 9L, 9L, 9L, 9L, 9L, 2L, 1L), .Label = c("1 hora em língua adicional", 
    "10 horas em língua adicional", "2 horas em língua adicional", 
    "3 horas em língua adicional", "5 horas em língua adicional", 
    "50% da carga- horária em língua adicional", "6 horas em língua adicional", 
    "Mais de 10 horas em língua adicional", "Não oferecemos este nível de ensino bilíngue na escola"
    ), class = "factor")), row.names = c(NA, -29L), class = "data.frame")

Upvotes: 1

Views: 759

Answers (1)

Andy Baxter
Andy Baxter

Reputation: 7626

Simple solution is to make sure that all factors have all the possible levels you may need - the warning messages are just letting you know that they're not all noted in all columns.

You can simply assign all columns the correct set of levels first, which will eliminate the warning messages. This will not change the values in any of the coluns, but will tell R that in principle it should expect all of these to be a valid value in all columns.

The line:

all_levels <- lapply(my_data, levels) |> reduce(c) |> unique()

Will concatenate all the levels you have already across all columns into a vector. fct_expand will then expand the list of possible values for each column, so that when fct_collapse checks each one it finds what it expects there.

library(tidyverse)

all_levels <- lapply(my_data, levels) |> reduce(c) |> unique()

my_data %>% 
  mutate(
    across(everything(), fct_expand, all_levels),
         across(everything(), fct_collapse,
                                        'Não oferta' = c('Não oferecemos este nível de ensino na escola', 
                                                         'Não oferecemos este nível de ensino bilíngue na escola'), 
                                        '> 20h' = c('Mais de 20 horas/ períodos semanais'),
                                        '> 10h' = c('Mais de 10 horas/ períodos semanais', 
                                                    'Mais de 10 horas em língua adicional'),
                                        '= 20h' = c('20 horas/ períodos semanais'),
                                        'Até 10h' = c('Até 10 horas/períodos semanais'),
                                        '= 1h' = c('1 hora em língua adicional'),
                                        '100% CH' = c('100% da carga-horária em língua adicional'),
                                        '> 15h' = c('Mais de 15 horas/ períodos semanais'),
                                        '> 30h' = c('Mais de 30 horas/ períodos semanais'),
                                        '50% CH' = c('50% da carga- horária em língua adicional',
                                                     '= 3h' = c('3 horas em língua adicional'),
                                                     '= 6h' = c('6 horas em língua adicional'),
                                                     '= 5h' = c('5 horas em língua adicional'),
                                                     '= 2h' = c('2 horas em língua adicional'),
                                                     '= 10h' = c('10 horas em língua adicional'),
                                                     '9h' = c('9 horas em língua adicional'),
                                                     '8h' = c('8 horas em língua adicional', 
                                                              '8 horas em língua adicional'), ## digitação
                                                     '3h' = c('3 horas em língua adicional'),
                                                     '4h' = c('4 horas em língua adicional'),
                                                     '7h' = c('7 horas em língua adicional'),
                                                     '2h' = c('2 horas em língua adicional'))))

fct_expand increases the levels of a factor - i.e. the list of valid values it can take - without modifying the data itself. The levels are distinct from the values, e.g.:

l <- factor(letters[1:3])

l
#> [1] a b c
#> Levels: a b c

l <- forcats::fct_expand(l, letters[1:5])

l
#> [1] a b c
#> Levels: a b c d e

Upvotes: 1

Related Questions