检查特定列中行的所有元素是否均不适用

时间:2019-11-25 10:57:34

标签: r apply purrr

如果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,但不知道如何将其替换为apply。

这将导致:

  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))

2 个答案:

答案 0 :(得分:2)

我们可以使用pmap_int中的purrr逐行遍历多列。

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))

答案 1 :(得分:1)

检查all(is.na(x))会在您需要TRUE的位置生成0,因此请在前面使用!^1转换为"numeric"。在R底下相当简单。

dat <- transform(dat, my_var=apply(dat[-1], 1, function(x) !all(is.na(x)))^1)
dat
#   my_var my_var_a my_var_b my_var_c my_var_others
# 1      0       NA       NA       NA            NA
# 2      1       NA        1       NA            NA
# 3      0       NA       NA       NA            NA
# 4      0       NA       NA       NA            NA