在 R 中:如何在给定另一列的值的情况下将函数应用于某一列

问题描述 投票:0回答:4

我有一个包含 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)
r na
4个回答
1
投票

基于

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

1
投票

一个简单的解决方案是捕获全部为

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

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)

0
投票

这是使用

rowwise()
进行
dplyr
操作的好例子。我们可以将复杂的逻辑语句包含在
replace()
中。 这是一个很好的方法,因为
dplyr
可以非常灵活地将该方法应用于不同的数据子集。

回答索引列D是否已存在:

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()
© www.soinside.com 2019 - 2024. All rights reserved.