在tidyverse中按行等效apply()?

时间:2017-07-06 14:49:25

标签: r dplyr tidyverse

我想在data.frame中插入一个新列,当行中至少有一个缺失值时该值为TRUE,否则为FALSE。

对于这个问题,apply是一个完美的用例:

编辑 - 添加了示例

tab <- data.frame(a = 1:10, b = c(NA, letters[2:10]), c = c(LETTERS[1:9], NA))

tab$missing <- apply(tab, 1, function(x) any(is.na(x)))

但是,我加载了strict包,并收到此错误:apply() coerces X to a matrix so is dangerous to use with data frames.Please use lapply() instead.

我知道我可以放心地忽略这个错误,但是,我想知道是否有办法使用其中一个tidyverse软件包来编码,以简单的方式。我尝试使用dplyr失败了:

tab %>% 
  rowwise() %>% 
  mutate(missing = any(is.na(.), na.rm = TRUE))

3 个答案:

答案 0 :(得分:5)

如果您想避免强制转换为矩阵,可以使用purrr::pmap,它会并行迭代列表的元素并将它们传递给函数:

library(tidyverse)

tab <- data_frame(a = 1:10, 
                  b = c(NA, letters[2:10]), 
                  c = c(LETTERS[1:9], NA))

tab %>% mutate(missing = pmap_lgl(., ~any(is.na(c(...)))))
#> # A tibble: 10 x 4
#>        a     b     c missing
#>    <int> <chr> <chr>   <lgl>
#>  1     1  <NA>     A    TRUE
#>  2     2     b     B   FALSE
#>  3     3     c     C   FALSE
#>  4     4     d     D   FALSE
#>  5     5     e     E   FALSE
#>  6     6     f     F   FALSE
#>  7     7     g     G   FALSE
#>  8     8     h     H   FALSE
#>  9     9     i     I   FALSE
#> 10    10     j  <NA>    TRUE

在函数中,需要c将传递给函数...的所有参数拉入向量中,该向量可以传递给is.na并使用any折叠。 *_lgl后缀pmap将结果简化为布尔向量。

请注意,虽然这可以避免强制转换为矩阵,但它不一定比方法更快,因为矩阵运算在R中高度优化。显式强制转换矩阵可能更有意义,例如

tab %>% mutate(missing = rowSums(is.na(as.matrix(.))) > 0)

返回同样的东西。

答案 1 :(得分:1)

这适用于示例数据:

library(tidyverse)

tab <- data_frame(a = 1:10, 
                  b = c(NA, letters[2:10]), 
                  c = c(LETTERS[1:9], NA))

tab_1 <- tab %>% mutate(missing = ifelse(is.na(b), TRUE, ifelse(is.na(c), TRUE, FALSE)))

> tab_1
    a    b    c missing
1   1 <NA>    A    TRUE
2   2    b    B   FALSE
3   3    c    C   FALSE
4   4    d    D   FALSE
5   5    e    E   FALSE
6   6    f    F   FALSE
7   7    g    G   FALSE
8   8    h    H   FALSE
9   9    i    I   FALSE
10 10    j <NA>    TRUE

答案 2 :(得分:0)

您可以使用complete.cases函数:

tab %>% mutate(missing = !complete.cases(.))

要删除具有一个或多个NA的行,请使用:

tab %>% filter(complete.cases(.))