我有一个包含 1 和 NA 的数据框。我想用零替换 NA,但如果整行都是 NA,则不会,因为这表明真正的 NA。
例如,这是一个简化的数据框:
A<-c(NA,NA,1,1)
B<-c(NA,NA,NA,1)
C<-c(1,NA,NA,NA)
df<-data.frame(A,B,C)
df$D<-ifelse(!is.na(df$A) | !is.na(df$B) | !is.na(df$C), 1,0)
A B C
NA NA 1
NA NA NA
1 NA NA
1 1 NA
A、B 和 C 列有 1 或空白 (NA)。我想用零 (0) 替换空格,但当 A、B 和 C 均为空白时则不行。我创建了 D 列作为 A B C 中是否有任何数据的指示器。现在我需要一个代码将 NA 替换为零。我希望这是有道理的。
我希望输出如下所示:
A B C D
0 0 1 1
0
1 0 0 1
1 1 0 1
我使用以下代码生成 D 列
df$D<-ifelse(!is.na(df$A) | !is.na(df$B) | !is.na(df$C), 1,0)
基于
rowSums
结果的方法(来自@Ritchie Sacramento的提示)
replace(df, rowSums(df, na.rm = T) > 0 & is.na(df), 0)
A B C
1 0 0 1
2 NA NA NA
3 1 0 0
4 1 1 0
一个简单的解决方案是捕获全部为
NA
的行,将所有 NA
替换为零,然后返回并重新填充 NA
:
all_na <- apply(is.na(df), 1, all)
df[is.na(df)] <- 0
df[all_na,] <- NA
否则你可以尝试这样:
data.frame(t(apply(df, 1, \(x) if (all(is.na(x))) x else replace(x, is.na(x), 0))))
# A B C
# 1 0 0 1
# 2 NA NA NA
# 3 1 0 0
# 4 1 1 0
# Sample DataFrame
df <- data.frame(A = c(NA, NA, 1, 1),
B = c(NA, NA, NA, 1),
C = c(1, NA, NA, NA))
# Create column D
df$D <- ifelse(!is.na(df$A) | !is.na(df$B) | !is.na(df$C), 1, 0)
# Replace NAs with zeros in columns A, B, and C, based on column D
df[df$D == 1, c("A", "B", "C")] <- lapply(df[df$D == 1, c("A", "B", "C")], function(x) ifelse(is.na(x), 0, x))
# Print the modified DataFrame
print(df)
这是使用
rowwise()
进行 dplyr
操作的好例子。我们可以将复杂的逻辑语句包含在replace()
中。
这是一个很好的方法,因为 dplyr
可以非常灵活地将该方法应用于不同的数据子集。
library(dplyr)
df |>
rowwise() |>
mutate(across(A:C, \(x) replace(x, is.na(x) & D, 0))) |>
ungroup()
# A tibble: 4 × 4
A B C D
<dbl> <dbl> <dbl> <dbl>
1 0 0 1 1
2 NA NA NA 0
3 1 0 0 1
dplyr::if_all
:df |>
rowwise() |>
mutate(across(A:C, \(x) replace(x, is.na(x) & !if_all(A:C, is.na), 0))) |>
ungroup()