【问题标题】:Data frames and is.nan()数据框和 is.nan()
【发布时间】:2011-08-11 18:42:09
【问题描述】:

我使用 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

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

is.na( )is.nan( ) 的文档中,参数类型似乎相同(尽管它们没有专门列出数据框):

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

【问题讨论】:

  • 不知道为什么会出现明显的不一致,但对于 is.nan 的逐个元素比较,请尝试 apply(my.df, c(1,2), is.nan)

标签: r


【解决方案1】:

来自?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.

数据框的列在技术上是“列表的元素”,因此is.nan(df) 返回一个长度等于数据框列数的向量,只有当列包含单个NaN 元素:

> is.nan(data.frame(a=NaN,b=NA,c=1))
    a     b     c 
 TRUE FALSE FALSE 

如果您想要与is.na 匹配的行为,请使用apply

sum(apply(my.df,2,is.nan))

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

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

 sum(is.nan(as.matrix(my.df)))

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

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

【讨论】:

  • 我很好奇为什么会这样实现。知道目标的常见用例是什么吗?
  • 并非如此。我认为is.na 是对数据的更一般描述,is.nan 是数字怪异的特定检测器。你可能不得不问 R-core 他们在想什么......
  • 在运行is.nan(data.frame(a=NaN,b=NA,c=1)) 时,我得到Error in is.nan(data.frame(a = NaN, b = NA, c = 1)) : default method not implemented for type 'list' 困惑。 @Ben Bolker
【解决方案2】:

由于某些奇怪的原因,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

【讨论】:

  • 嗨@Adam它重置了结果df数据帧的索引。有什么办法也可以保留索引
猜你喜欢
  • 2017-08-24
  • 2018-10-10
  • 2018-08-31
  • 2013-09-26
  • 1970-01-01
  • 2021-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多