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

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

6.16.1 问题

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

6.16.2 方案

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

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

d <- read.csv(header = TRUE, text = "
x,y,value
a,one,1
,,5
b,two,4
c,three,10
")

d
#>   x     y value
#> 1 a   one     1
#> 2             5
#> 3 b   two     4
#> 4 c three    10

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

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

## 移除第二行
d <- d[-2, ]
d
#>   x     y value
#> 1 a   one     1
#> 3 b   two     4
#> 4 c three    10

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

6.16.2.1 使用 droplevels()

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

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

6.16.2.2 使用 vapply() 和 lapply()

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

## 找出哪些列是因子
factor_cols <- vapply(d, is.factor, logical(1))

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

6.16.3 另见

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