使用列表合併因子級別
有時候需要將因子級別合併到更少的組中,這可能是因為其中一個類別中的資料稀疏。當你對類別名稱進行不同的拼寫或大小寫時,也可能會發生這種情況。以這個因素為例
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
然而,該表並不代表資料的真實分佈,並且類別可以有效地減少為三種型別:藍色,綠色和紅色。提供了三個例子。第一個說明了什麼似乎是一個明顯的解決方案,但實際上並沒有提供解決方案。第二個提供了一個可行的解決方案,但是冗長且計算成本高。第三種不是一個明顯的解決方案,但相對緊湊且計算效率高。
使用 factor
(factor_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
請注意,有重複的級別。我們仍然有三個類別為藍色,它沒有完成我們鞏固水平的任務。此外,還有一個警告,即不推薦使用重複級別,這意味著此程式碼將來可能會生成錯誤。
使用 ifelse
(ifelse_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
方法的兩倍。但是,除了非常非常大量的資料時,執行時間的差異很可能以微秒或毫秒來衡量。由於時間差異很小,效率無需指導決定使用哪種方法。相反,請使用熟悉且舒適的方法,以及你和你的協作者在將來的稽核中將會理解的方法。