【问题标题】:How to deal with NA values in a categorical variable?如何处理分类变量中的 NA 值?
【发布时间】:2020-05-22 02:53:53
【问题描述】:

我遇到了一个奇怪的问题,希望有人能帮忙。 我在 R 中有一个具有 8 个类(级别)的事实变量,如下所示:

> levels(data_testing$land_cover)
[1] "COMMERCIAL"                   "GOVERNMENT AND INSTITUTIONAL" "NOT AVAILABLE"              
[4] "OPEN AREA"                    "PARKS AND RECREATIONAL"       "RESIDENTIAL"                
[7] "RESOURCE AND INDUSTRIAL"      NA 

如您所见,NA 是变量“land_cover.”的级别之一,级别的频率如下:

COMMERCIAL GOVERNMENT AND INSTITUTIONAL                NOT AVAILABLE
                         236                          150                          469
                   OPEN AREA       PARKS AND RECREATIONAL                  RESIDENTIAL
                         908                          108                         6034
     RESOURCE AND INDUSTRIAL                         <NA>
                        1584                         2505

所以它说有 2505 个 NA 值。但是,当我计算这样一个变量的总缺失值时,它显示没有:

sum (is.na(data_testing$land_cover))
[1] 0

我的问题是,如果有人知道我如何重命名,重估这个NA?我尝试将NA 替换或重命名为其他名称,但NAs 无法识别为级别。

我的最终目标是将所有NA 值添加到“NOT AVAILABLE”类中并摆脱NA 类。但是,显然,在替换或重估函数中,NA 不能被识别为一个类。

我真的很感谢您提前提供的帮助。

干杯-

【问题讨论】:

  • 可以加dput(head(data_testing$land_cover))吗?

标签: r rename missing-data data-cleaning categorical-data


【解决方案1】:

您的向量的levels 有问题。我不知道它是如何创建的(假设它是以编程方式完成的),但让我们组成一个类似的向量并说明它为什么与您的测试不匹配。

首先,factor 只是一个integer 向量,有两个区别:"levels" 的属性,它是级别的字符串向量;它被归类为"factor"

dput(factor(letters[1:3]))
# structure(1:3, .Label = c("a", "b", "c"), class = "factor")

让我们手动构建一个:

vec <- 1:3
attr(vec, "levels") <- c("A", "B", NA, "D")
vec
# [1] 1 2 3
# attr(,"levels")
# [1] "A" "B" NA  "D"

还不是一个因素,所以整数仍然显示 not-NA

class(vec) <- "factor"
vec
# [1] A    B    <NA>
# Levels: A B <NA> D

dput(vec)
# structure(c(1L, 2L, NA), .Label = c("A", "B", NA, "D"), class = "factor")

attributes(vec)
# $levels
# [1] "A" "B" NA  "D"
# $class
# [1] "factor"

所以我们没有对vec 中的整数做任何事情,但现在其中一个显示为NA。很有趣。

不幸的是,我们知道在 factor 类下面,数字仍然是 1、2 和 3,而不是 NA,所以我们不应该对此感到完全惊讶:

is.na(vec)
# [1] FALSE FALSE FALSE
as.integer(vec)
# [1] 1 2 3

要找出vec 引用NA 中的哪一个,

as.character(vec)
# [1] "A" "B" NA 
is.na(as.character(vec))
# [1] FALSE FALSE  TRUE

并找出哪个级别NA

is.na(levels(vec))
# [1] FALSE FALSE  TRUE FALSE

如果您想替换 levelNA,您可以尝试以下操作:

lvls <- levels(vec)
lvls[is.na(lvls)] <- "NOT AVAILABLE"
levels(vec) <- lvls

vec
# [1] A             B             NOT AVAILABLE
# Levels: A B NOT AVAILABLE D

(我从来没有真正喜欢过不带引号的因子显示方式,因为上面的 Levels: 可能含糊不清。)


顺便说一句,许多辅助函数试图阻止你这样做。例如:

vec <- 1:3
attr(vec, "levels") <- LETTERS[1:4]
class(vec) <- "factor"
dput(vec)
# structure(1:3, .Label = c("A", "B", "C", "D"), class = "factor")
attr(vec, "levels") <- c("A", "B", NA, "D")
dput(vec)
# structure(1:3, .Label = c("A", "B", NA, "D"), class = "factor")

注意我们如何 (i) 仍然是整数 1 到 3; (ii) NA 级别。但是,如果我们正式地这样做,

levels(vec) <- c("A", "B", NA, "D")
dput(vec)
# structure(c(1L, 2L, NA), .Label = c("A", "B", "D"), class = "factor")

我们丢失了一个整数!我们失去了NA 级别。

【讨论】:

    猜你喜欢
    • 2020-04-05
    • 2014-09-02
    • 1970-01-01
    • 1970-01-01
    • 2015-10-10
    • 2021-08-22
    • 2021-12-27
    • 2018-01-22
    • 1970-01-01
    相关资源
    最近更新 更多