选择NA级的因子值

时间:2018-11-22 08:20:50

标签: r

让我们考虑以下变量:

 y <- factor(5:1, levels = 1:5, labels <- c(1:4, NA))

选择没有标签NA的所有值的最佳方法是什么?

> !is.na(y)
[1] FALSE FALSE FALSE FALSE FALSE

可以使用因子值,但是记录NA的值很麻烦:

> as.integer(y)
[1] 1 2 3 4 5
> as.integer(y) == which(is.na(levels(y)))
[1] FALSE FALSE FALSE FALSE  TRUE

转换为字符似乎可行,但这在计算上似乎不是最佳选择:

> as.character(y)
[1] "1" "2" "3" "4" NA
> is.na(as.character(y))
[1] FALSE FALSE FALSE FALSE  TRUE

还有其他(有效的)想法很容易处理吗?

注意:这个问题专门涉及将NA作为要素水平。一般而言,这与选择值无关。事实证明,最通用的方法可以按预期方式进行处理-请参阅下面的注释。

注释2:由于y[!y %in% NA]的工作方式,似乎可以使用%in%。从文档中:“因素,原始向量和列表将转换为字符向量。”即%in%的使用实际上等同于上述基于as.character的方法。不过,应避免这种转换-这是此问题带来的问题。

顺便说一句,这是上述方法的次要标准:

library(microbenchmark)
y <- factor(rep(5:1, 1000000), levels = 1:5, labels <- c("foo", "foo bar", "foobar bar", "foo foobar", NA))
microbenchmark(
        as.integer(y) == which(is.na(levels(y))),
        is.na(as.character(y)),
        y %in% NA,
        is.na(levels(y)[y]),
        ## times = 1e5,
        times = 100,
        check = function (values) {
            all(sapply(values[-1], function(x) identical(values[[1]], x)))
        }
    )

Unit: milliseconds
                                     expr       min   median       max
 as.integer(y) == which(is.na(levels(y)))  8.566085 15.92278  46.45769
                   is.na(as.character(y)) 24.554066 29.05405  58.22167
                                y %in% NA 58.836131 64.57089 104.53393
                      is.na(levels(y)[y]) 29.748583 34.27200 131.22975

所以最好的办法可能是将第一种方法包装为我想的函数。差异不大。不幸的是,microbenchmark()不会返回有关内存使用的任何信息。

问候 汤姆

0 个答案:

没有答案