使用列表合併因子級別

有時候需要將因子級別合併到更少的組中,這可能是因為其中一個類別中的資料稀疏。當你對類別名稱進行不同的拼寫或大小寫時,也可能會發生這種情況。以這個因素為例

set.seed(1)
colorful <- sample(c("red", "Red", "RED", "blue", "Blue", "BLUE", "green", "gren"),
                   size = 20,
                   replace = TRUE)
colorful <- factor(colorful)

由於 R 區分大小寫,因此該向量的頻率表如下所示。

table(colorful)
colorful  
blue  Blue  BLUE green  gren   red   Red   RED  
   3     1     4     2     4     1     3     2

然而,該表並不代表資料的真實分佈,並且類別可以有效地減少為三種型別:藍色,綠色和紅色。提供了三個例子。第一個說明了什麼似乎是一個明顯的解決方案,但實際上並沒有提供解決方案。第二個提供了一個可行的解決方案,但是冗長且計算成本高。第三種不是一個明顯的解決方案,但相對緊湊且計算效率高。

使用 factorfactor_approach)整合關卡

factor(as.character(colorful),
       levels = c("blue", "Blue", "BLUE", "green", "gren", "red", "Red", "RED"),
       labels = c("Blue", "Blue", "Blue", "Green", "Green", "Red", "Red", "Red"))
 [1] Green Blue  Red   Red   Blue  Red   Red   Red   Blue  Red   Green Green Green Blue  Red   Green
[17] Red   Green Green Red  
Levels: Blue Blue Blue Green Green Red Red Red
Warning message:
In `levels<-`(`*tmp*`, value = if (nl == nL) `as.character(labels)` else paste0(labels,  :
  duplicated levels in factors are deprecated

請注意,有重複的級別。我們仍然有三個類別為藍色,它沒有完成我們鞏固水平的任務。此外,還有一個警告,即不推薦使用重複級別,這意味著此程式碼將來可能會生成錯誤。

使用 ifelseifelse_approach)鞏固關卡

factor(ifelse(colorful %in% c("blue", "Blue", "BLUE"),
       "Blue",
       ifelse(colorful %in% c("green", "gren"),
              "Green",
              "Red")))
 [1] Green Blue  Red   Red   Blue  Red   Red   Red   Blue  Red   Green Green Green Blue  Red   Green
[17] Red   Green Green Red  
Levels: Blue Green Red

此程式碼生成所需的結果,但需要使用巢狀的 ifelse 語句。雖然這種方法沒有任何問題,但管理巢狀的 ifelse 語句可能是一項繁瑣的工作,必須小心謹慎。

使用列表整合因子級別(list_approach

合併級別的一種不太明顯的方法是使用一個列表,其中每個元素的名稱是所需的類別名稱,元素是應該對映到所需類別的因子級別的字元向量。這具有直接處理因子的 levels 屬性的附加優點,而無需分配新物件。

levels(colorful) <- 
     list("Blue" = c("blue", "Blue", "BLUE"),
          "Green" = c("green", "gren"),
          "Red" = c("red", "Red", "RED"))
 [1] Green Blue  Red   Red   Blue  Red   Red   Red   Blue  Red   Green Green Green Blue  Red   Green
[17] Red   Green Green Red  
Levels: Blue Green Red

對每種方法進行基準測試

執行每種方法所需的時間總結如下。 (為了空間,未顯示生成此摘要的程式碼)

Unit: microseconds
          expr     min      lq      mean   median      uq     max neval cld
        factor  78.725  83.256  93.26023  87.5030  97.131 218.899   100  b 
        ifelse 104.494 107.609 123.53793 113.4145 128.281 254.580   100   c
 list_approach  49.557  52.955  60.50756  54.9370  65.132 138.193   100 a

列表方法的執行速度大約是 ifelse 方法的兩倍。但是,除了非常非常大量的資料時,執行時間的差異很可能以微秒或毫秒來衡量。由於時間差異很小,效率無需指導決定使用哪種方法。相反,請使用熟悉且舒適的方法,以及你和你的協作者在將來的稽核中將會理解的方法。