首页 > 解决方案 > 仅省略某一列中不与其他 NA 重叠的 NA

问题描述

假设我有一个如下所示的数据框:

>df
col1   col2   col3

 12    NA      2 
 21    11     NA
 NA     2     NA
 3     NA     NA
 NA    NA      4
 8     12      5
 41    39      9

我想省略 NA,但是 col3 中的 NA 是一条宝贵的信息,所以我不想在没有更多信息的情况下用任何其他值填充它。因此,我只想省略与 col3 中的 NA 不重叠的 NA。

所以它看起来像这样:

>df
col1   col2   col3

 21    11     NA
 NA     2     NA
 3     NA     NA
 8     12      5
 41    39      9

col2 和 col1 中的 NA 仍然存在的唯一原因是因为删除它们的行会导致 col3 中的 NA 也被删除,这是我想要防止的。因此,我可以容忍 col1 和 col2 中剩余的 NA。

我有什么方便的方法可以做到这一点,或者有什么包可以解决这个问题吗?我试过使用过滤器:

df <- df %>% filter(complete.cases(df[, -3]))

但它变成了这样,因为有重叠 NA :

 >df
 col1   col2   col3

 21    11     NA
 8     12      5
 41    39      9

有什么想法吗?先谢谢了~

标签: rdataframemissing-data

解决方案


我们可以创造一个条件rowSums

df1[!(rowSums(is.na(df1[-3])) > 0 & !is.na(df1[[3]])),]
#  col1 col2 col3
#2   21   11   NA
#3   NA    2   NA
#4    3   NA   NA
#6    8   12    5
#7   41   39    9

当我们执行 时rowSums(is.na(df1[-3])) > 0,它会检查前两列中的任何 NA 并为这些情况返回 TRUE

rowSums(is.na(df1[-3])) > 0
#[1]  TRUE FALSE  TRUE  TRUE  TRUE FALSE FALSE

但是,我们要删除第一行,因为NA'col3' 中没有该行

接下来我们检查NA'col3' 中的 s

is.na(df1[[3]])
#[1] FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE

无论哪里有 TRUE,我们都想保留它。所以,如果我们这样做&,它将返回NA两者的共同点

(rowSums(is.na(df1[-3])) > 0 & !is.na(df1[[3]]))
#[1]  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE

即第 1 行和第 5 行在两个列块中都有 NA。否定它会改变TRUE-> FALSEFALSE-> TRUE

!(rowSums(is.na(df1[-3])) > 0 & !is.na(df1[[3]]))
#[1] FALSE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE

哪些行可以有两个集合没有任何 NA 或 'col3' 有 NA 和其他行可能有或没有 NA


或者使用相同的逻辑filter

library(dplyr)
df1  %>%
     filter(!(rowSums(is.na(.[-3])) > 0 & !is.na(col3)))

数据

df1 <- structure(list(col1 = c(12L, 21L, NA, 3L, NA, 8L, 41L), col2 = c(NA, 
11L, 2L, NA, NA, 12L, 39L), col3 = c(2L, NA, NA, NA, 4L, 5L, 
9L)), class = "data.frame", row.names = c(NA, -7L))

推荐阅读