基于匹配的字符串或跨列子集的NA,逐行进行突变

问题描述

任何建议如何在一行中跨多列匹配字符串?

改编自 Remove rows where all variables are NA using dplyr,其中它们仅匹配各列之间的NA,并对其进行过滤-不创建新变量。

玩具示例:

library(dplyr)
df <- tibble(a = c('a','a',NA),b1 = c('b','c',NA,b2 = c('d',b3 = c('e',b4 = c('f',NA))
df

# A tibble: 4 x 5
  a     b1    b2    b3    b4   
  <chr> <chr> <chr> <chr> <chr>
1 a     b     d     e     f    
2 a     c     NA    NA    NA   
3 a     NA    NA    NA    NA   
4 NA    NA    NA    NA    NA 

要创建一个新变量all_na(如果整行都是NA:

df %>% 
  rowwise() %>% 
  mutate(all_na = all(is.na(across())))


# A tibble: 4 x 6
# Rowwise: 
  a     b1    b2    b3    b4    all_na
  <chr> <chr> <chr> <chr> <chr> <lgl> 
1 a     b     d     e     f     FALSE 
2 a     c     NA    NA    NA    FALSE 
3 a     NA    NA    NA    NA    FALSE 
4 NA    NA    NA    NA    NA    TRUE   

如果仅列的子集(以'b'开头)为NA b_is_na,则创建一个新变量

df %>% 
  rowwise() %>% 
  mutate(b_is_na = all(is.na(across(starts_with('b'))))) %>% 
  ungroup()

# A tibble: 4 x 6
  a     b1    b2    b3    b4    b_is_na
  <chr> <chr> <chr> <chr> <chr> <lgl>  
1 a     b     d     e     f     FALSE  
2 a     c     NA    NA    NA    FALSE  
3 a     NA    NA    NA    NA    TRUE   
4 NA    NA    NA    NA    NA    TRUE   

问题:

但是,我不确定如何在行内创建变量,因为列的子集是字符串匹配或NA,例如'c' or NA

所需的输出:

# A tibble: 4 x 6
  a     b1    b2    b3    b4    b_is_na
  <chr> <chr> <chr> <chr> <chr> <lgl>  
1 a     b     d     e     f     FALSE  
2 a     c     NA    NA    NA    TRUE  
3 a     NA    NA    NA    NA    TRUE   
4 NA    NA    NA    NA    NA    TRUE   

解决方法

在逻辑base R上,rowSums选项和有效的矢量化选项为matrix

nm1 <- startsWith(names(df),'b')
df$b_is_na <- rowSums(df[nm1] == 'c'|is.na(df[nm1])) > 0
df$b_is_na
#[1] FALSE  TRUE  TRUE  TRUE

它也可以与mutate

一起使用
library(dplyr)
df %>%
  mutate(b_is_na = rowSums(select(.,starts_with('b')) == 
             'c'|is.na(select(.,starts_with('b')))) > 0)
# A tibble: 4 x 6
#  a     b1    b2    b3    b4    b_is_na
#  <chr> <chr> <chr> <chr> <chr> <lgl>  
#1 a     b     d     e     f     FALSE  
#2 a     c     <NA>  <NA>  <NA>  TRUE   
#3 a     <NA>  <NA>  <NA>  <NA>  TRUE   
#4 <NA>  <NA>  <NA>  <NA>  <NA>  TRUE 

注意:使用rowwise效率不高

或与c_across一起使用,但这可能不是最佳选择

df %>% 
   rowwise %>%
   mutate(b_is_na = {
        tmp <- c_across(starts_with('b'))
         any(is.na(tmp)|tmp == 'c') }) %>%
   ungroup
# A tibble: 4 x 6
#  a     b1    b2    b3    b4    b_is_na
#  <chr> <chr> <chr> <chr> <chr> <lgl>  
#1 a     b     d     e     f     FALSE  
#2 a     c     <NA>  <NA>  <NA>  TRUE   
#3 a     <NA>  <NA>  <NA>  <NA>  TRUE   
#4 <NA>  <NA>  <NA>  <NA>  <NA>  TRUE   

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...