因子(Factor)

R 的因子(factor)變數是專門用來儲存類別資料的變數,它同時具有字串與整數的特性。

建立因子變數

若要建立一個因子變數,可以使用 factor 函數:

colors <- c("red", "yellow", "green", "red", "green")
colors.factor <- factor(colors)
colors.factor
[1] red    yellow green  red    green 
Levels: green red yellow

因子變數在輸出時,看起來跟一般的字元向量類似,而最後一行的 levels 會列出這個因子變數所有的類別。我們可以使用 levels 這個函數取得因子的 levels:

levels(colors.factor)
[1] "green"  "red"    "yellow"

nlevels 則可以取得因子 levels 的數量:

nlevels(colors.factor)
[1] 3

在建立因子變數時,可以使用 levels 參數指定 levels 的排列順序:

colors.factor2 <- factor(colors,
  levels = c("red", "yellow", "green"))
colors.factor2
[1] red    yellow green  red    green 
Levels: red yellow green

labels 參數則可以指定個類別的名稱:

colors.factor3 <- factor(colors,
  levels = c("red", "yellow", "green"),
  labels = c("R", "Y", "G"))
colors.factor3
[1] R Y G R G
Levels: R Y G

在建立 data frame 時,R 預設會將文字的資料轉為因子:

values <- c(12, 54, 23, 83, 2)
colors <- c("red", "yellow", "green", "red", "green")
my.table <- data.frame(values, colors)
my.table
  values colors
1     12    red
2     54 yellow
3     23  green
4     83    red
5      2  green
class(my.table$colors)
[1] "factor"

改變因子的 Levels

因子變數中的元素值只能是 levels 中的其中一種或是缺失值(NA),如果將因子的元素指定為其他的字串,該元素就會被設定為缺失值,並產生警告訊息:

colors.factor[1] <- "blue"
Warning message:
In `[<-.factor`(`*tmp*`, 1, value = "blue") :
  invalid factor level, NA generated
colors.factor
[1] <NA>   yellow green  red    green
Levels: green red yellow

如果要新增一個 levels 中沒有的類別資料,可以先使用 levels 函數先新增一個 level,再指定新的值:

colors.levels <- levels(colors.factor)
levels(colors.factor) <- c(colors.levels, "blue")
colors.factor[1] <- "blue"
colors.factor
[1] blue   yellow green  red    green 
Levels: green red yellow blue

在更動因子變數的 levels 時,要注意其排列的順序,新增的 level 要放在最後面,如果順序搞錯會造成資料錯誤,若要避免順序錯亂的問題,可以使用 list 的方式指定:

levels(colors.factor) <- list(
  blue = "blue", green = "green",
  red = "red", yellow = "yellow")
colors.factor[1] <- "blue"
colors.factor
[1] blue   yellow green  red    green 
Levels: blue green red yellow

relevel 可以重新排序因子變數的 levels,將指定的 level 放在第一個位置:

relevel(colors.factor, "red")
[1] blue   yellow green  red    green 
Levels: red blue green yellow

移除因子的 Levels

有時候在處理一些原始的文字資料時,會出現類似這樣英文大小寫不統一的狀況:

colors.raw <- c("Red", "yellow", "green", "red", "green")
colors.factor <- factor(colors.raw)
colors.factor
[1] Red    yellow green  red    green 
Levels: green red Red yellow

而經過修正之後,就會出現一些沒有用的 levels。

colors.factor[1] <- "red"
unique(colors.factor)
[1] red    yellow green 
Levels: green red Red yellow

若要移除因子變數中沒有用到的 levels,可以使用 droplevels 函數:

colors.factor <- droplevels(colors.factor)
colors.factor
[1] red    yellow green  red    green 
Levels: green red yellow

droplevels 也可以直接處理 data frame 之內的因子欄位:

colors.raw <- c("Red", "yellow", "green", "red", "green")
values <- c(12, 54, 23, 83, 2)
my.table2 <- data.frame(values, colors.raw)
my.table2$colors.raw
[1] Red    yellow green  red    green 
Levels: green red Red yellow
my.table2$colors.raw[1] <- "red"
unique(my.table2$colors.raw)
[1] red    yellow green
Levels: green red Red yellow
my.table2 <- droplevels(my.table2)
my.table2$colors.raw
[1] red    yellow green  red    green 
Levels: green red yellow