【问题标题】:How to collapse categories or recategorize variables?如何折叠类别或重新分类变量?
【发布时间】:2011-03-17 02:08:19
【问题描述】:

在 R 中,我有 600,000 个分类变量,每个分类变量被分类为“0”、“1”或“2”。

我想做的是折叠“1”和“2”并自行留下“0”,这样在重新分类后“0”=“0”; “1”=“1”和“2”=“1”。最后,我只希望“0”和“1”作为每个变量的类别。

另外,如果可能的话,我宁愿不创建 600,000 个新变量,如果我可以用新值替换现有变量那就太好了!

最好的方法是什么?

【问题讨论】:

    标签: r categories collapse


    【解决方案1】:

    我发现使用factor(new.levels[x]) 更通用:

    > x <- factor(sample(c("0","1","2"), 10, replace=TRUE)) 
    > x
     [1] 0 2 2 2 1 2 2 0 2 1
    Levels: 0 1 2
    > new.levels<-c(0,1,1)
    > x <- factor(new.levels[x])
    > x
     [1] 0 1 1 1 1 1 1 0 1 1
    Levels: 0 1
    

    新的层级向量的长度必须与 x 中的层数相同,因此您也可以使用字符串和 NA 进行更复杂的重新编码

    x <- factor(c("old", "new", NA)[x])
    > x
     [1] old    <NA>   <NA>   <NA>   new <NA>   <NA>   old   
     [9] <NA>   new    
    Levels: new old
    

    【讨论】:

      【解决方案2】:

      recode() 对此有点矫枉过正。您的情况取决于当前的编码方式。假设你的变量是 x。

      如果是数字

      x <- ifelse(x>1, 1, x)
      

      如果是角色

      x <- ifelse(x=='2', '1', x)
      

      如果它是级别 0,1,2 的因子

      levels(x) <- c(0,1,1)
      

      其中任何一个都可以跨数据框 dta 应用于变量 x。比如……

       dta$x <- ifelse(dta$x > 1, 1, dta$x)
      

      或者,一个框架的多个列

       df[,c('col1','col2'] <- sapply(df[,c('col1','col2'], FUN = function(x) ifelse(x==0, x, 1))
      

      【讨论】:

        【解决方案3】:

        car中有一个函数recode(应用回归的伴侣):

        require("car")    
        recode(x, "c('1','2')='1'; else='0'")
        

        或者在普通 R 中为您的情况:

        > x <- factor(sample(c("0","1","2"), 10, replace=TRUE))
        > x
         [1] 1 1 1 0 1 0 2 0 1 0
        Levels: 0 1 2
        > factor(pmin(as.numeric(x), 2), labels=c("0","1"))
         [1] 1 1 1 0 1 0 1 0 1 0
        Levels: 0 1
        

        更新:要重新编码数据框 tmp 的所有分类列,您可以使用以下代码

        recode_fun <- function(x) factor(pmin(as.numeric(x), 2), labels=c("0","1"))
        require("plyr")
        catcolwise(recode_fun)(tmp)
        

        【讨论】:

        • 感谢您的回复!这就是我将其专门应用于我的数据的方式。我的数据采用 data.frame 的形式,我想维护它: data
        【解决方案4】:

        我喜欢 dplyr 中可以快速重新编码值的功能。

         library(dplyr)
         df$x <- recode(df$x, old = "new")
        

        希望这会有所帮助:)

        【讨论】:

          【解决方案5】:

          请注意,如果您只希望结果是 0-1 二元变量,则可以完全放弃因子:

          f <- sapply(your.data.frame, is.factor)
          your.data.frame[f] <- lapply(your.data.frame[f], function(x) x != "0")
          

          第二行也可以写得更简洁(但可能更隐晦)

          your.data.frame[f] <- lapply(your.data.frame[f], `!=`, "0")
          

          这会将您的因素转换为一系列逻辑变量,其中“0”映射到FALSE,其他任何内容都映射到TRUEFALSETRUE 将被大多数代码视为 0 和 1,这反过来在分析中应该给出与使用级别为“0”和“1”的因子基本相同的结果。事实上,如果它没有给出相同的结果,那就会让人怀疑分析的正确性......

          【讨论】:

            【解决方案6】:

            您可以使用sjmisc 包的rec 函数,它可以一次重新编码一个完整的数据帧(假设所有变量至少具有相同的重新编码值)。

            library(sjmisc)
            mydf <- data.frame(a = sample(0:2, 10, T),
                               b = sample(0:2, 10, T),
                               c = sample(0:2, 10, T))
            
            > mydf
               a b c
            1  1 1 0
            2  1 0 1
            3  0 2 0
            4  0 1 0
            5  1 0 0
            6  2 1 1
            7  0 1 1
            8  2 1 2
            9  1 1 2
            10 2 0 1
            
            mydf <- rec(mydf, "0=0; 1,2=1")
            
               a b c
            1  1 1 0
            2  1 0 1
            3  0 1 0
            4  0 1 0
            5  1 0 0
            6  1 1 1
            7  0 1 1
            8  1 1 1
            9  1 1 1
            10 1 0 1
            

            【讨论】:

              【解决方案7】:

              使用来自 tidyverse 的 forcats 包的解决方案

              library(forcats)
              
              > x <- factor(sample(c("0","1","2"), 10, replace=TRUE))
              > x
              [1] 1 1 1 0 1 0 2 0 1 0
              Levels: 0 1 2
                  
              > fct_collapse(x, "1" = c("1", "2"))
              [1] 1 1 1 0 1 0 1 0 1 0
              Levels: 0 1
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2015-12-23
                • 2015-05-12
                • 1970-01-01
                • 2019-10-12
                • 2019-03-29
                相关资源
                最近更新 更多