首页 > 解决方案 > 检查特定列中的所有行元素是否为 NA

问题描述

如果 my_var_a 到 my_var_c 都是 NA,我希望 my_var 为 0

# A tibble: 4 x 5
  my_var my_var_a my_var_b my_var_c my_var_others
   <int>    <int>    <int>    <int>         <int>
1      0       NA       NA       NA            NA
2      1       NA        1       NA            NA
3      0       NA       NA       NA            NA
4     NA       NA       NA       NA            NA

我得到了我想要的结果:

library(tidyverse)

df %>% mutate(my_var = if_else(apply(select(., my_var_a:my_var_c), 1, function(x) all(is.na(x))), 0L, my_var))

有没有更简单的方法来做到这一点,或者至少有一种使用的方法purrr?我调查了pmap但无法弄清楚它将如何取代应用。

结果是:

  my_var my_var_a my_var_b my_var_c my_var_others
   <int>    <int>    <int>    <int>         <int>
1      0       NA       NA       NA            NA
2      1       NA        1       NA            NA
3      0       NA       NA       NA            NA
4      0       NA       NA       NA            NA 

这是数据框:

structure(list(my_var = c(0L, 1L, 0L, NA), my_var_a = c(NA_integer_, 
NA_integer_, NA_integer_, NA_integer_), my_var_b = c(NA, 1L, 
NA, NA), my_var_c = c(NA_integer_, NA_integer_, NA_integer_, 
NA_integer_), my_var_others = c(NA_integer_, NA_integer_, NA_integer_, 
NA_integer_)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-4L))

标签: rapplypurrr

解决方案


我们可以使用pmap_intfrompurrr逐行迭代多个列。

library(dplyr)
library(purrr)

df %>% mutate(my_var = pmap_int(select(., my_var_a:my_var_c), ~any(!is.na(c(...)))))

#  my_var my_var_a my_var_b my_var_c my_var_others
#   <int>    <int>    <int>    <int>         <int>
#1      0       NA       NA       NA            NA
#2      1       NA        1       NA            NA
#3      0       NA       NA       NA            NA
#4      0       NA       NA       NA            NA

在基数 R 中,我们可以使用rowSums并将 1 分配给至少有一个非 NA 值的行。

cols <- paste0("my_var_",letters[1:3])
df$my_var <- +(rowSums(is.na(df[cols])) < length(cols))

推荐阅读