Разработка функции, чтобы фильтр не отбрасывал NA - PullRequest
0 голосов
/ 13 февраля 2019

Я только недавно был укушен dplyr :: filter, удаляющим большое количество NA из моей таблицы при фильтрации.Я в основном работал над полными наборами данных, но теперь углубляюсь в более сложные данные, где я хочу провести сравнение.Поэтому я хочу создать функцию с теми же возможностями, что и у фильтра, но без удаления NA.Вот некоторые предложения: Почему фильтр dplyr отбрасывает значения NA из факторной переменной? или Как отфильтровать данные без потери строк NA, используя dplyr , однако они являются громоздкими решениями при работе с большим количествомнедостающие значения данных и множество сравнений.Ниже приведен пример некоторых способов обойти это.

Это примеры данных с отсутствующими NA в обоих столбцах A и B

df = tibble(A = rep(c(1,2,3,NA,NA),10000),
            B = rep(c(NA,1,2,3,4),10000))

Это то, что я хочу сделать интуитивно.Возвращайте значения, где A не равно B, однако отбрасывает все NA (как и ожидалось).

df %>% filter(A != B)

1-е решение: решение для устранения этой проблемы состоит в использовании% в% от базы R, новам нужно делать эту строку построчно, а затем разгруппировать, чтобы это замедляло процесс.Но дает правильный результат, сохраняя NA, когда они появляются в A или B.

df %>% rowwise() %>%  filter(!A %in% B) %>% ungroup()

2-е решение: Другой вариант, который ранее был предложен, использует |вернуть A и B, если они NA.

df %>% filter(A != B|is.na(A)|is.na(B))

Теперь, если вы выполняете многократную фильтрацию и сравнение, это становится утомительным, и вы, вероятно, где-нибудь разберетесь!Поэтому возможно создать функцию, которая автоматически имеет встроенную функцию is.na ().Может быть, что-то вроде этого.

    filter_keepna = function(data, expression){
data %>% filter(expression|is.na(column1)|is.na(column2)
}

У меня недостаточно знаний, чтобы заставить что-то подобное работать.Но я предполагаю из всех комментариев на разных платформах, что это то, что требуется.

Ответы [ 2 ]

0 голосов
/ 13 февраля 2019

Попробуйте coalesce

df %>% filter(coalesce(A != B, TRUE))
0 голосов
/ 13 февраля 2019

В вашей функции вы можете использовать функции для аккуратной оценки из пакета rlang.Функции enquo(), f_lhs() и quo_get_expr() могут помочь извлечь переменные из выражения.Также вам нужен оператор bang bang (!!) для интерпретации предложений.В вашем примере это:

filter_keepna <- function(data, expre){
  expre <- enquo(expre) #Quotation 

  data %>% 
    filter(!!expre | #!! is a tidy evaluator

             # get quoted left variable from expre
             is.na(!!f_lhs(quo_get_expr(expre))) |

             # get quoted right variable from expre
             is.na(!!f_rhs(quo_get_expr(expre))))
}

Использование функции filter_keepna() в данных вашего примера:

df = tibble(A = rep(c(1,2,3,NA,NA),10000),
            B = rep(c(NA,1,2,3,4),10000))

filter_keepna(df, A != B)
# A tibble: 40,000 x 2
#        A     B
#     <dbl> <dbl>
#  1     2     1
#  2     3     2
#  3    NA     3
#  4    NA     4
#  5     2     1
#  6     3     2
#  7    NA     3
#  8    NA     4
#  9     2     1
# 10     3     2
# # ... with 39,990 more rows

Подробная информация в справочнике цитат и Справочник получателей Quosure пакета rlang..........

...