32

在将数据帧与另一个 im 合并后,偶尔会出现随机 NA。我想将这些 NA 设置为 0,以便我可以使用它们进行计算。

我试图这样做:

    bothbeams.data = within(bothbeams.data, {
      bothbeams.data$x.x = ifelse(is.na(bothbeams.data$x.x) == TRUE, 0, bothbeams.data$x.x)
      bothbeams.data$x.y = ifelse(is.na(bothbeams.data$x.y) == TRUE, 0, bothbeams.data$x.y)
    })

其中 $xx 是一列, $xy 是另一列,但这似乎不起作用。

4

5 回答 5

68

您可以只使用的输出is.na直接替换为子集:

bothbeams.data[is.na(bothbeams.data)] <- 0

或者有一个可重现的例子:

dfr <- data.frame(x=c(1:3,NA),y=c(NA,4:6))
dfr[is.na(dfr)] <- 0
dfr
  x y
1 1 0
2 2 4
3 3 5
4 0 6

但是,在包含也有缺失值的因子的数据框中使用此方法时要小心:

> d <- data.frame(x = c(NA,2,3),y = c("a",NA,"c"))
> d[is.na(d)] <- 0
Warning message:
In `[<-.factor`(`*tmp*`, thisvar, value = 0) :
  invalid factor level, NA generated

有用”:

> d
  x    y
1 0    a
2 2 <NA>
3 3    c

...但在这种情况下,您可能只想专门更改数字列,而不是整个数据框。参见,例如,下面使用的答案dplyr::mutate_if

于 2012-04-13T10:43:45.013 回答
20

如果您想将其添加到管道中,则使用mutate_allfrom的解决方案:dplyrdplyr

library(dplyr)
df %>%
  mutate_all(funs(ifelse(is.na(.), 0, .)))

结果:

   A B C
1  0 0 0
2  1 0 0
3  2 0 2
4  3 0 5
5  0 0 2
6  0 0 1
7  1 0 1
8  2 0 5
9  3 0 2
10 0 0 4
11 0 0 3
12 1 0 5
13 2 0 5
14 3 0 0
15 0 0 1

如果在任何情况下您只想替换数字列中的 NA,我认为这可能是建模中的情况,您可以使用mutate_if

library(dplyr)
df %>%
  mutate_if(is.numeric, funs(ifelse(is.na(.), 0, .)))

或在基础 R 中:

replace(is.na(df), 0)

结果:

   A    B C
1  0    0 0
2  1 <NA> 0
3  2    0 2
4  3 <NA> 5
5  0    0 2
6  0 <NA> 1
7  1    0 1
8  2 <NA> 5
9  3    0 2
10 0 <NA> 4
11 0    0 3
12 1 <NA> 5
13 2    0 5
14 3 <NA> 0
15 0    0 1

更新

dplyr 1.0.0,across介绍:

library(dplyr)
# Replace `NA` for all columns
df %>%
  mutate(across(everything(), ~ ifelse(is.na(.), 0, .)))

# Replace `NA` for numeric columns
df %>%
  mutate(across(where(is.numeric), ~ ifelse(is.na(.), 0, .)))

数据:

set.seed(123)
df <- data.frame(A=rep(c(0:3, NA), 3), 
                 B=rep(c("0", NA), length.out = 15), 
                 C=sample(c(0:5, NA), 15, replace = TRUE))
于 2017-09-15T15:29:03.100 回答
1

添加到 James 的示例中,在对包含 NA 的数据帧执行计算时,您似乎总是必须创建一个中间体。

例如,将数据框中的两列(A 和 B)加在一起dfr

temp.df <- data.frame(dfr) # copy the original
temp.df[is.na(temp.df)] <- 0
dfr$C <- temp.df$A + temp.df$B # or any other calculation
remove('temp.df')

remove当我这样做时,我会用/丢弃中间体rm

于 2015-03-01T14:17:04.863 回答
1

您可以replace_na()tidyr包中使用

df %>% replace_na(list(column1 = 0, column2 = 0)

于 2021-04-19T17:04:20.497 回答
-1

为什么不试试这个

  na.zero <- function (x) {
        x[is.na(x)] <- 0
        return(x)
    }
    na.zero(df)
于 2017-02-04T09:09:21.950 回答