【问题标题】:How to replace only NA data with 0 in R and not the NaN value in a dataframe?如何仅将 NA 数据替换为 R 中的 0 而不是数据框中的 NaN 值?
【发布时间】:2015-01-15 06:57:29
【问题描述】:

我的问题是,当您想更改 NA 值时,如何避免更改 NaN 值:

我使用了这段代码,但它会改变两者:

dataframe[is.na(dataframe)] <- 0

我看到了link 并知道发生这种情况的原因是:

 is.na(NaN)
 [1] TRUE

但我真的想在这两者之间有所不同,所以我用它来更改 NaN,然后​​使用之前的代码

dataframe[is.nan(dataframe)] <-"NAN"

我得到这个错误:

default method not implemented for type 'list'

那我该怎么做呢?

提前谢谢你,

【问题讨论】:

  • 谢谢@RichardScriven,是的,你是对的,也可以在此声明为错误的情况下替换 0,很抱歉没有先考虑清楚!

标签: r dataframe nan na


【解决方案1】:

我将此作为@akrun 答案的替代方法。

您收到错误的原因是因为 is.na 有处理 data.frames (base:::is.na.data.frame) 的方法,但 is.nan 没有。 (请注意,data.frame 实际上只是一个列表,其中每个命名元素的长度与其他元素的长度相同,即每一列。)

您会遇到的一个问题是,当您将字符串分配给(否则为数字?)data.frame 中的NaN 值时,您会将每列的其余部分转换为字符。您应该关注的是找到 include NAexclude NaN 的逻辑。

有几种方法可以处理它。如果要处理所有列,那么使用@akrun 的数据,以下可能对您有用:

as.data.frame(lapply(dat, function(x) {
    x[is.na(x) & !is.nan(x)] <- 0
    x
}))
##     V1  V2  V3 V4  V5
## 1    0   6   0  9   5
## 2  NaN   9   2 10   6
## 3    4 NaN NaN  5   1
## 4   10   4 NaN  9 NaN
## 5    8   6   1  1   6
## 6    7 NaN   7 10 NaN
## 7    9 NaN   5  1   0
## 8    2   2   0  3   8
## 9    8   6   6  0 NaN
## 10   9   7   0  8   8

【讨论】:

  • 不确定使用循环而不是矢量化方法的原因是什么
  • 这不是循环,但如果您只想在选定列上运行此转换,您可以使用 for 循环遍历特定列,将它们就地修复。跨度>
  • lapply for 循环
  • 我理解你的语义断言,所以请原谅我之前的概括。对我来说,我将所有*apply 组合为对vector/list/matrix/data.frame 的所有元素进行操作的函数,并将文字forwhile 组合为“for”循环。反对@akrun 的矢量化方法的一个理由是is.nan 不能在data.frame 上工作。他的方法在这里行得通,但如果需要更多控制,他的矢量化方法可能过于不加选择。这就是我以“@akrun 的替代方法”开头的原因之一。 (有人可能会说 lapply 更像是一个 foreach 循环。;-)
【解决方案2】:

试试

dat[is.na(dat=='NaN')] <- 0
dat
 #   V1  V2  V3 V4  V5
 #1    0   6   0  9   5
 #2  NaN   9   2 10   6
 #3    4 NaN NaN  5   1
 #4   10   4 NaN  9 NaN
 #5    8   6   1  1   6
 #6    7 NaN   7 10 NaN
 #7    9 NaN   5  1   0
 #8    2   2   0  3   8
 #9    8   6   6  0 NaN
 #10   9   7   0  8   8

或者

 indx <- is.na(dat)
 dat[indx][!is.nan(dat[indx])] <- 0

数据

set.seed(42)
dat <- as.data.frame(matrix(sample(c(1:10, NA, NaN), 
                            5*10, replace=TRUE), ncol=5))

【讨论】:

  • 非常感谢@akrun
猜你喜欢
  • 1970-01-01
  • 2021-08-30
  • 2015-09-08
  • 2020-01-04
  • 2014-09-20
  • 2023-01-27
  • 2013-09-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多