在tidyverse中按行应用apply()的等效方法?

11

我希望在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()将X强制转换为矩阵,因此在使用数据框时是危险的。请改用lapply()。

我知道我可以安全地忽略这个错误,但是我想知道是否有一种使用tidyverse包之一的简单方法进行编码。我尝试过dplyr,但没有成功:

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

2
你尝试过使用 purrr::by_row() 吗? - Hanjo Odendaal
3
很遗憾,这个已经被废弃了,可以使用purrrlyr代替。 - alistaire
3
顺便说一句,你也可以使用“Margin = 1”方法避免令人讨厌的“apply”,并在“rowSums(is.na(tab))> 0”的向量化行中执行某些操作。 - Sotos
2
尝试这样做:apply(is.na(tab), 1, any)vapply(split(tab, 1:nrow(tab)), f, logical(1)),其中 f 是问题中的匿名函数。 - G. Grothendieck
我认为这个问题的标题有误导性。标题应该是“如何使用Tidyverse向数据框中添加列”。至今还没有回答什么是Tidyverse相当于按行应用函数的方法。建议编辑队列当前已满。 - Kasper Thystrup Karstensen
@HanjoOdendaal实际上提供了这个问题的一个答案,尽管by_row现在已经被弃用。 - Kasper Thystrup Karstensen
3个回答

9

如果您想避免强制转换为矩阵,可以使用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
您可以使用complete.cases函数:
tab %>% mutate(missing = !complete.cases(.))

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

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接