使用addNA()后找到NA值

时间:2013-06-25 15:58:29

标签: r categories na

我有一个带有一堆分类变量的数据框。其中一些包含NA,我使用addNA函数将它们转换为显式因子级别。当我尝试将它们视为NA时,我的问题就出现了,它们似乎没有注册。

这是我的示例数据集并试图“找到”NA:

df1 <- data.frame(id = 1:200, y =rbinom(200, 1, .5),
                  var1 = factor(rep(c('abc','def','ghi','jkl'),50)))
df1$var2 <- factor(rep(c('ab c','ghi','jkl','def'),50))
df1$var3 <- factor(rep(c('abc','ghi','nop','xyz'),50))

df1[df1$var1 == 'abc','var1'] <- NA

df1$var1 <- addNA(df1$var1)

df1$isNaCol <- ifelse(df1$var1 == NA, 1, 0);summary(df1$isNaCol)
df1$isNaCol <- ifelse(is.na(df1$var1), 1, 0);summary(df1$isNaCol)
df1$isNaCol <- ifelse(df1$var1 == 'NA', 1, 0);summary(df1$isNaCol)
df1$isNaCol <- ifelse(df1$var1 == '<NA>', 1, 0);summary(df1$isNaCol)

当我输入??addNA时,我没有得到任何匹配。这是灰色市场功能还是什么?任何建议将不胜感激。

3 个答案:

答案 0 :(得分:4)

使用通常的比较运算符测试与NA的相等性总是产生NA ---你想要is.na。另外,在is.na上调用factor测试每个级别索引(而不是与该索引关联的值),因此您希望首先将factor转换为character向量。

df1$isNaCol <- ifelse(is.na(as.character(df1$var1)), 1, 0);summary(df1$isNaCol)

答案 1 :(得分:4)

请注意,这是在调用addNA() 之前使用OP的数据完成的。

了解addNA()对此数据的作用是有益的。

> head(df1$var1)
[1] <NA> def  ghi  jkl  <NA> def 
Levels: abc def ghi jkl
> levels(df1$var1)
[1] "abc" "def" "ghi" "jkl"
> head(addNA(df1$var1))
[1] <NA> def  ghi  jkl  <NA> def 
Levels: abc def ghi jkl <NA>
> levels(addNA(df1$var1))
[1] "abc" "def" "ghi" "jkl" NA

addNA正在改变因子的级别,使得缺失性(NA)是一个级别,默认情况下R将其忽略为{{1值得采取的当然是缺失。它也剥离了NA信息 - 从某种意义上说它不再是未知的,而是一个“缺失”类别的一部分。

查看NA我们addNA的帮助。

如果我们看一下?addNA的定义,我们会发现它正在做的就是改变水平

addNA

请注意,它不会更改数据 - of the factor, not changing the data any: > addNA function (x, ifany = FALSE) { if (!is.factor(x)) x <- factor(x) if (ifany & !any(is.na(x))) return(x) ll <- levels(x) if (!any(is.na(ll))) ll <- c(ll, NA) factor(x, levels = ll, exclude = NULL) } 仍然存在于因子中。我们可以通过以下方式复制NA的大部分行为:

addNA

但是因为with(df1, factor(var1, levels = c(levels(var1), NA), exclude = NULL)) > head(with(df1, factor(var1, levels = c(levels(var1), NA), exclude = NULL))) [1] <NA> def ghi jkl <NA> def Levels: abc def ghi jkl <NA> 现在是一个级别,这些条目表示通过NA 表示丢失了这解释了你做的第二个比较不工作(你在哪里使用is.na())。

您从is.na()获得的唯一精确性是,如果它已作为一个级别存在,则它不会将addNA添加为级别。另外,如果数据中没有NA,您可以通过ifany停止将NA添加为关卡。

你出错的地方是尝试使用通常的比较方法(第二个例子除外)比较NA。如果我们不知道观察值和NA观察值,我们如何将它与某些东西进行比较?好吧,我们不能,除了NA的内部表示。这是由NA函数完成的:

is.na()

因此我会这样做(完全不使用> with(df1, head(is.na(var1), 10)) [1] TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE TRUE FALSE

addNA

如果您希望将其作为df1 <- transform(df1, isNaCol = is.na(var1)) > head(df1) id y var1 var2 var3 isNaCol 1 1 1 <NA> ab c abc TRUE 2 2 0 def ghi ghi FALSE 3 3 0 ghi jkl nop FALSE 4 4 0 jkl def xyz FALSE 5 5 0 <NA> ab c abc TRUE 6 6 1 def ghi ghi FALSE 1变量,只需添加0,如

as.numeric()

我认为你真的出错的地方是想要在df1 <- transform(df1, isNaCol = as.numeric(is.na(var1))) 级别附加NA级别。我认为addNA()是一个方便函数,可用于table()之类的内容,甚至可以使用addNA()之前不需要事先使用的参数,例如:

> with(df1, table(var1, useNA = "ifany"))
var1
 abc  def  ghi  jkl <NA> 
   0   50   50   50   50

答案 2 :(得分:3)

与NA相比的任何东西都是NA;这就是为什么你的第一个摘要都是NA。

addNA函数会将因子中的任何NA观察值更改为新级别。然后,该级别被赋予标签 NA(字符模式)。底层变量本身不再具有任何NA。这就是你的第二个摘要全部为0的原因。

要查看有多少观察结果具有NA水平,请使用Matthew Plourde发布的内容。