Как использовать Forcats::Fct_Collapse в функции на разных фреймах данных с разными уровнями фактора

library(tidyverse)
library(forcats)

У меня есть два простых кадра данных (код внизу), и я хочу создать новую перекодированную переменную, свернув столбец "Animal". Я обычно делаю это с помощью forcats::fct_collapse. Тем не менее, я хочу сделать функцию для применения fct_collapse ко многим различным фреймам данных, которые имеют одинаковые переменные, за исключением того, что в некоторых из них может отсутствовать один или два уровня фактора. Например, в этом случае в Df2 отсутствует "Rhino".

Есть ли способ, которым я могу изменить код (используя tiyverse), чтобы отсутствующие категории факторов были возвращены как NA? В этом примере я знаю, что это "Rhino", но в моих реальных данных могут быть другие недостающие уровни. Я открыт для других опций, кроме forcats::fct_collapse, но я бы хотел остаться в сфере Tidyverse.

REC <- function(Df, Data){

Df %>% 
mutate(NEW = fct_collapse(Data, One = c("Cat","Dog","Snake"),
                          Two = c("Elephant","Bird","Rhino")))
}

REC(Df1,Animal) - this works
REC(DF2,Animal) - this doesn't, it throws an error because of "Rhino"

Пример данных:

Animal <- c("Cat","Dog","Snake","Elephant","Bird","Rhino")
Code <- c(101,222,434,545,444,665)
Animal2 <- c("Cat","Dog","Snake","Elephant","Bird")
Code2 <- c(101,222,434,545,444)

Df1 <- data_frame(Code, Animal)

Df2 <- data_frame(Code2, Animal2) %> %rename(Animal = Animal2)

1 ответ

Решение

Вот одна идея для вас. Первоначально я пытался иметь два аргумента в моей функции. Один был для фрейма данных, а другой был столбцом с именами животных. Но эта попытка не удалась. У меня было сообщение об ошибке "Ошибка в mutate_impl(.data, точки): столбец new должна быть длина 5 (количество строк) или одна, а не 6."Поэтому я решил не включать имя столбца в функцию; я четко сказал Animal в моей функции. Затем все заработало. Идея состояла в том, чтобы создать факторную переменную с отсутствующими названиями животных. Это было сделано в factor() с setdiff(), Как только у меня были все имена животных, я использовал fct_collapse(),

myfun <- function(mydf){

         animals <- c("Cat", "Dog", "Snake", "Elephant", "Bird", "Rhino")

         mydf %>%
         mutate(new =  factor(Animal, levels = c(unique(Animal), setdiff(animals, Animal))),
                new = fct_collapse(new, One = c("Cat", "Dog", "Snake"),
                                       Two = c("Elephant", "Bird", "Rhino"))) -> x
         x}

> myfun(Df2)
# A tibble: 5 x 3
  Code2 Animal   new  
  <dbl> <chr>    <fct>
1   101 Cat      One  
2   222 Dog      One  
3   434 Snake    One  
4   545 Elephant Two  
5   444 Bird     Two  

> myfun(Df1)
# A tibble: 6 x 3
   Code Animal   new  
  <dbl> <chr>    <fct>
1   101 Cat      One  
2   222 Dog      One  
3   434 Snake    One  
4   545 Elephant Two  
5   444 Bird     Two  
6   665 Rhino    Two  

ПРИМЕЧАНИЕ: следующая функция та же самая, за исключением того, что у меня есть два аргумента. Это не работает. Если возможны какие-либо изменения, пожалуйста, дайте мне знать.

myfun2 <- function(mydf, mycol){

         animals <- c("Cat", "Dog", "Snake", "Elephant", "Bird", "Rhino")

         mydf %>%
         mutate(new =  factor(mycol, levels = c(unique(mycol), setdiff(animals, mycol))),
               new = fct_collapse(new, One = c("Cat", "Dog", "Snake"),
                                       Two = c("Elephant", "Bird", "Rhino"))) -> x
        x}

> myfun2(Df2, Animal)
Error in mutate_impl(.data, dots) : 
Column `new` must be length 5 (the number of rows) or one, not 6
Другие вопросы по тегам