使用 cut() 生成因子

Using cut() to make factor

我正在尝试从 R 中的数字变量中创建因子变量。我想跟踪 NA 和我正在创建的新容器。在新的 bin 中,有些数字在有效范围内,有些则不在范围内。我关心垃圾箱本身,但想创建一个 "invalid" 级别来容纳任何不在指定范围内的东西。

这是一个例子:

library(reshape)

fac <- c(-1, 1, 2, 3, 4, 100, NA)
fac <- cut(fac, c(-Inf, 1, 2, 3, Inf))
fac <- addNA(fac)
combine_factor(fac, 
           variable=order(levels(fac))[c(2,3,5)],
           other.label = "Invalid")

这会给我一些输出,这些输出的水平是我想要的间隔、NA 或无效。

但是,我遇到的问题是我不想使用数字对变量进行编码,因为我有多个不同的数据集,而且并非所有数据集都包含因子的每个级别。

如果我更改变量使其不包含任何特定水平的因子:

fac <- c(-1, 1, 3, 4, 100, NA)

我一直收到错误消息:

Error in factor(nvar[as.numeric(fac)], labels=c(levels(fac)[variable], : invalid 'labels'; length 4 should be 1 or 3.

输出 1(有效,因为我没有出现 0 次的关卡):

[1] (1,2]   (1,2]   (2,3]   <NA>    Invalid Invalid Invalid
Levels: (1,2] (2,3] <NA> Invalid

输出 2(其中一级:(1,2] 出现 0 次):

[1]   (2,3]   <NA>    Invalid Invalid Invalid 
Levels: (1,2] (2,3] <NA> Invalid

第二种情况是我遇到错误的地方。

有什么办法可以解决这个错误吗?

我对 combine_factor 函数了解不多,但是自己编写似乎很容易....

这是一个基本示例:

NewLevs <- function(fac, keep, others = "Invalid") {
  lf <- levels(fac)
  nl <- c(setNames(as.list(lf[keep]), lf[keep]),
    setNames(as.list(lf[-keep]), rep(others, length(lf)-length(keep))))
  levels(fac) <- nl
  fac
}

下面是一些示例数据:

fac1 <- c(-1, 1, 2, 3, 4, 100, NA)
fac1 <- addNA(cut(fac1, c(-Inf, 1, 2, 3, Inf)))

fac2 <- c(-1, 1, 3, 4, 100, NA)
fac2 <- addNA(cut(fac2, c(-Inf, 1, 2, 3, Inf)))

使函数起作用:

fac1
# [1] (-Inf,1] (-Inf,1] (1,2]    (2,3]    (3, Inf] (3, Inf] <NA>    
# Levels: (-Inf,1] (1,2] (2,3] (3, Inf] <NA>
NewLevs(fac1, c(2, 3, 5))
# [1] Invalid Invalid (1,2]   (2,3]   Invalid Invalid <NA>   
# Levels: (1,2] (2,3] <NA> Invalid


fac2
# [1] (-Inf,1] (-Inf,1] (2,3]    (3, Inf] (3, Inf] <NA>    
# Levels: (-Inf,1] (1,2] (2,3] (3, Inf] <NA>
NewLevs(fac2, c(2, 3, 5))
# [1] Invalid Invalid (2,3]   Invalid Invalid <NA>   
# Levels: (1,2] (2,3] <NA> Invalid

可以更改所需级别以及不需要级别的标签:

NewLevs(fac2, c(1, 2, 3), "Wrong")
# [1] (-Inf,1] (-Inf,1] (2,3]    Wrong    Wrong    Wrong   
# Levels: (-Inf,1] (1,2] (2,3] Wrong