数据框和is.nan()

Zac*_*ach 20 r

sum(is.na(my.df))用来检查我的数据框是否包含任何按预期工作的NA,但是sum(is.nan(my.df))没有按照我的预期工作.

> my.df <- data.frame(a=c(1, 2, 3), b=c(5, NA, NaN))
> my.df
  a   b
1 1   5
2 2  NA
3 3 NaN
> is.na(my.df)
         a     b
[1,] FALSE FALSE
[2,] FALSE  TRUE
[3,] FALSE  TRUE
> is.nan(my.df)
    a     b 
FALSE FALSE 
> sum(is.na(my.df))
[1] 2
> sum(is.nan(my.df))
[1] 0
Run Code Online (Sandbox Code Playgroud)

噢亲爱的.是否存在行为不一致的原因?是因为缺乏实施,还是故意的?返回值is.nan(my.df)表示什么?是否有充分的理由不在is.nan()整个数据框架上使用?

在该文档is.na( )is.nan( ),参数类型似乎是相同的(虽然他们没有明确列出的数据帧):

is.na():x R要测试的对象:默认方法处理原子向量,列表和pairlists. is.nan():x R要测试的对象:默认方法处理原子向量,列表和pairlists.

Ben*_*ker 21

来自?is.nan:

All elements of logical,integer and raw vectors are considered not to be NaN, and
elements of lists and pairlists are also unless the element is a length-one numeric
or complex vector whose single element is NaN.
Run Code Online (Sandbox Code Playgroud)

数据框的列在技术上是"列表的元素",因此is.nan(df)返回一个长度等于数据帧的列数的向量,TRUE仅当列由单个NaN元素组成时:

> is.nan(data.frame(a=NaN,b=NA,c=1))
    a     b     c 
 TRUE FALSE FALSE 
Run Code Online (Sandbox Code Playgroud)

如果您希望行为匹配is.na,请使用apply:

sum(apply(my.df,2,is.nan))
Run Code Online (Sandbox Code Playgroud)

答案是1,而不是2,因为is.nan(NA)FALSE...

编辑:或者,您可以将数据框转换为矩阵:

 sum(is.nan(as.matrix(my.df)))
Run Code Online (Sandbox Code Playgroud)

更新:在问题被提出后,在R版本2.14(2011年10月)中,此行为很快(两个月)发生了变化:来自NEWS文件,

o is.finite(),is.infinite()和is.nan()的默认方法现在发出错误,如果它们的参数不是原子向量.

  • 当运行`is.nan(data.frame(a=NaN,b=NA,c=1))` 我得到`Error in is.nan(data.frame(a = NaN, b = NA, c = 1) ) : 没有为类型“list”实现默认方法困惑。@本博克 (2认同)

Ada*_*son 8

由于某些奇怪的原因,该is.nan函数不适用于列表。为什么它与我不同,is.na这超出了我的范围,似乎是一个语言设计问题。然而,有一个简单的解决方案:

df <- data.frame(a=c(1, 2, 3), b=c(5, NA, NaN)) 
df <- data.frame(sapply(df, function(x) ifelse(is.nan(x), NA, x)))
df
  a  b
1 1  5
2 2 NA
3 3 NA
Run Code Online (Sandbox Code Playgroud)