Пропускать только те NA, которые не перекрываются с другими NA в определенном столбце - PullRequest
1 голос
/ 17 февраля 2020

Допустим, у меня есть фрейм данных, который выглядит следующим образом:

>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, но NA в col3 - это ценная информация, поэтому я не хочу заполните его любым другим значением без дополнительной информации. Таким образом, я хочу опустить NA, который не перекрывается с NA только в col3.

Таким образом, это выглядело бы так:

>df
col1   col2   col3

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

Единственная причина, по которой NA в col2 и col1 все еще существует, потому что удаление их строки приведет к удалению также NA в col3, что это то, что я хочу предотвратить. Таким образом, я могу терпеть эти оставшиеся NA от col1 и col2.

Есть ли какой-нибудь удобный для меня способ сделать это или любой пакет для решения этой проблемы? Я пытался использовать фильтр:

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

Но вместо этого все стало так, потому что есть перекрывающийся NA:

 >df
 col1   col2   col3

 21    11     NA
 8     12      5
 41    39      9

Есть мысли? Заранее спасибо ~

1 Ответ

1 голос
/ 17 февраля 2020

Мы можем создать условие с помощью 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

Но мы хотим удалить эту первую строку, потому что в 'col3'

для этой строки нет NA Далее мы проверяем NA s в 'col3'

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

Везде, где есть ИСТИНА, мы хотим сохранить его. Итак, если мы сделаем &, он вернет NA, общий для обоих

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

, то есть 1-я и 5-я строки имеют NA в обоих блоках столбцов. Отрицание этого меняет TRUE-> FALSE и FALSE-> TRUE

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

, то есть строки, которые могут иметь оба набора, не имеющие NA, или 'col3' с NA, а другие строки могут иметь или не иметь NA


или используйте те же логи c в filter

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

data

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))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...