Сравните факторы с разными уровнями в кадре данных

Я пытаюсь сравнить два фактора в кадре данных, чтобы создать новую переменную. Факторы имеют разные уровни, что вызывает ошибку.

Вот воспроизводимый пример

library(dplyr)
library(forcats)

mtcars %>% 
  select(gear, carb) %>% 
  mutate_at(c("gear", "carb"), ~as_factor(.)) %>%
  mutate(gear_vs_carb = gear == carb)

И вот ошибка:

Error in Ops.factor(gear, carb) : level sets of factors are different

Я понимаю, что могу провести сравнение, преобразовав факторы в символы или числа и / или добавив неиспользуемые уровни к факторам, чтобы уровни совпадали, например Как сравнить два фактора с разными уровнями?

Но можно ли провести сравнение напрямую с исходными факторами?

Результат должен выглядеть так же, как и для

mtcars %>% 
  select(gear, carb) %>% 
  mutate(gear_vs_carb = gear == carb)

Спасибо за помощь!


person maia-sh    schedule 08.12.2019    source источник


Ответы (2)


== не будет работать с классом factor. Одним из вариантов может быть преобразование в character и выполнение поэлементного сравнения или, если намерение состоит в том, чтобы сравнить levels, sort levels, выполнить сравнение и заключить в all

library(dplyr)
mtcars %>% 
   select(gear, carb) %>% 
   mutate_at(c("gear", "carb"), ~as_factor(.)) %>%
   mutate(gear_vs_carb =  all(sort(levels(gear)) == sort(levels(carb))))
   #or use intersect
   #  mutate(gear_vs_carb = length(intersect(levels(gear), 
   #          levels(carb))) == nlevels(gear))

Если мы выполняем поэлементное сравнение, преобразуйте его в класс character с помощью as.character, а затем выполните сравнение

mtcars %>% 
   select(gear, carb) %>% 
   mutate_at(c("gear", "carb"), ~as_factor(.)) %>%
   mutate(gear_vs_carb = as.character(gear) == as.character(carb))
person akrun    schedule 08.12.2019

Вам нужно преобразовать в символ только один множитель, а не оба.

mtcars %>% 
  select(gear, carb) %>% 
  mutate_at(c("gear", "carb"), as_factor) %>%
  mutate(gear_vs_carb = gear == as.character(carb))
person G. Grothendieck    schedule 08.12.2019