6.16 重计算数据框所有因子列的水平

6.16.1 问题

你想要重新计算一个数据框中所有因子列(变量)的因子水平。

6.16.2 方案

有时候在读入和清理数据之后,你会发现数据(数据框)结果中有的因子列有一些不存在的因子水平。

例如,下面的d有一个空行。当它被读入时,因子列会出现水平 "",它不应该是数据的一部分。

  1. d <- read.csv(header = TRUE, text = "
  2. x,y,value
  3. a,one,1
  4. ,,5
  5. b,two,4
  6. c,three,10
  7. ")
  8. d
  9. #> x y value
  10. #> 1 a one 1
  11. #> 2 5
  12. #> 3 b two 4
  13. #> 4 c three 10
  14. str(d)
  15. #> 'data.frame': 4 obs. of 3 variables:
  16. #> $ x : Factor w/ 4 levels "","a","b","c": 2 1 3 4
  17. #> $ y : Factor w/ 4 levels "","one","three",..: 2 1 4 3
  18. #> $ value: int 1 5 4 10

即便移除了空行,因子中仍有水平 ""

  1. # 移除第二行
  2. d <- d[-2, ]
  3. d
  4. #> x y value
  5. #> 1 a one 1
  6. #> 3 b two 4
  7. #> 4 c three 10
  8. str(d)
  9. #> 'data.frame': 3 obs. of 3 variables:
  10. #> $ x : Factor w/ 4 levels "","a","b","c": 2 3 4
  11. #> $ y : Factor w/ 4 levels "","one","three",..: 2 4 3
  12. #> $ value: int 1 4 10

6.16.2.1 使用 droplevels()

最简单的方式是使用 droplevels() 函数:

  1. d1 <- droplevels(d)
  2. str(d1)
  3. #> 'data.frame': 3 obs. of 3 variables:
  4. #> $ x : Factor w/ 3 levels "a","b","c": 1 2 3
  5. #> $ y : Factor w/ 3 levels "one","three",..: 1 3 2
  6. #> $ value: int 1 4 10

6.16.2.2 使用 vapply() 和 lapply()

为了重新计算所有因子列的水平,我们使用以 is.factor() 为参数的 vapply()函数去找出哪些列是因子,然后再利用以 factor()函数为参数的 lapply() 操作将那些列重新计算因子水平。

  1. # 找出哪些列是因子
  2. factor_cols <- vapply(d, is.factor, logical(1))
  3. # 把 factor() 函数应用到那些列,并把结果赋回 d
  4. d[factor_cols] <- lapply(d[factor_cols], factor)
  5. str(d)
  6. #> 'data.frame': 3 obs. of 3 variables:
  7. #> $ x : Factor w/ 3 levels "a","b","c": 1 2 3
  8. #> $ y : Factor w/ 3 levels "one","three",..: 1 3 2
  9. #> $ value: int 1 4 10

6.16.3 另见

关于重计算一个因子变量水平的信息,参见重计算因子水平