for 循环中 if else 和 ifelse 的行为差异

时间:2021-01-28 14:32:01

标签: r for-loop

我正在尝试执行 for loop 以将 NA 的某些列中的 data.frame 值替换为零。这是我的数据示例:

data <- structure(list(x1 = c(441, 457, 455, 475, 490, 547, 21, 17, 16, 
26), x2 = c(25, 28, 24, 20, 21, 28, 0, 1, 0, 1), x3 = c(3, 1, 
2, 2, 0, 2, 0, 0, 0, 0), x4 = c(0, 1, NA, NA, NA, NA, 0, 0, 0, 
0), x5 = c(1, 2, 2, 5, 2, 0, 0, 0, NA, NA)), row.names = c(NA, 
10L), class = "data.frame")

将 if else 应用于 for loop 有效:

for (i in 1:5) {
  for (j in 1:nrow(data)) {
    if(is.na(data[j,i])){
      data[j,i] = 0 
    } else {
      data[j,i] =  data[j,i]
    }
  }
}

但是当我在 for loop 中应用 ifelse 时,它​​不起作用:

for (i in 1:5) {
      for (j in 1:nrow(data)) {
        ifelse(is.na(data[j,i]), 0, data[j,i])
      }
}

有人能帮我理解这些函数的行为差异吗?非常感谢。

2 个答案:

答案 0 :(得分:1)

您可以尝试 replace + is.na 以提高效率

data <- replace(data,is.na(data),0)

这样

> data
    x1 x2 x3 x4 x5
1  441 25  3  0  1
2  457 28  1  1  2
3  455 24  2  0  2
4  475 20  2  0  5
5  490 21  0  0  2
6  547 28  2  0  0
7   21  0  0  0  0
8   17  1  0  0  0
9   16  0  0  0  0
10  26  1  0  0  0

答案 1 :(得分:0)

您需要将结果分配给某些东西:

for (i in 1:5) {
      for (j in 1:nrow(data)) {
        data[j, i] <- ifelse(is.na(data[j,i]), 0, data[j,i])
      }
}

但是请注意,在您的情况下使用两个 for loops 不是最佳做法。 立即改进如下:

for (i in 1:5) {
    data[, i] <- ifelse(is.na(data[ ,i]), 0, data[ ,i])
}

更好的是:您可以使用 tidyverse 包:

library(tidyverse)
data <- mutate(data, across(everything, ~if_else(is.na(.x), 0, .x)))