设计一个函数,使过滤器不会丢失NA

时间:2019-02-13 03:00:15

标签: r filter dplyr na

我只是最近才被dplyr :: filter咬住,在过滤时从我的小词中删除了大量NA。我主要从事完整数据集的工作,但现在尝试进入更混乱的数据中进行比较。因此,我想创建一个与过滤器具有相同功能但不删除NA的函数。以下是一些建议:Why does dplyr's filter drop NA values from a factor variable?How to filter data without losing NA rows using dplyr,但是在处理大量缺少的数据值和进行许多比较时,它们是繁琐的解决方案。下面是一些解决方法的示例。

这是示例数据,在A和B列中都缺少NAs

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)

第一个解决方案:解决此问题的一种方法是使用基数R中的%in%,但是您需要逐行执行此操作然后取消分组,因此这会减慢该过程。但是,当NA出现在A或B中时,可以通过保留它们来给出正确的结果。

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

第二个解决方案:先前建议的另一个选项是使用|。如果它们是NA,则返回A和B。

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 :(得分:1)

在您的函数中,您可以使用这些函数从rlang包中进行整洁的评估。 enquo()f_lhs()quo_get_expr()函数可以帮助从表达式中提取变量。另外,您还需要“爆炸”运算符(!!)来解释安全性。在您的示例中,是:

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

rlang软件包的quotation referenceQuosure getters reference中的详细信息。 .........

答案 1 :(得分:0)

尝试coalesce

df %>% filter(coalesce(A != B, TRUE))