【问题标题】:How to Use Forcats::Fct_Collapse in a Function Across Different Dataframes with Different Factor Levels如何在具有不同因子级别的不同数据帧的函数中使用 Forcats::Fct_Collapse
【发布时间】:2018-02-02 03:35:13
【问题描述】:
library(tidyverse)
library(forcats)

我有两个简单的数据框(代码在底部),我想通过折叠“动物”列来创建一个新的重新编码变量。我通常用 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)

【问题讨论】:

    标签: r tidyverse forcats


    【解决方案1】:

    这是给你的一个想法。我最初试图在我的函数中有两个参数。一个用于数据框,另一个是包含动物名称的列。但这次尝试失败了。我收到一条错误消息,说“mutate_impl(.data, dots) 中的错误:列 new 的长度必须为 5(行数)或 1,而不是 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
    

    【讨论】:

    • 对于第一个示例,“动物”向量是否必须与 fct_collapse 的顺序相同,或者只要动物包含所有因子水平,它就可以工作?
    • 忽略上面的问题,我让它与我的真实数据一起工作。这是一个很好的解决方案,非常感谢!
    • @Mike 我刚看到你的第一条消息,我正要写评论。现在我不必这样做了!我很高兴你找到了办法。 :)
    猜你喜欢
    • 2013-03-16
    • 2013-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-24
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    相关资源
    最近更新 更多