일치하는 문자열 또는 열 하위 집합의 NA를 기반으로 행 방식으로 변경

Aug 19 2020

행 내에서 여러 열에 걸쳐 문자열을 일치시키는 방법에 대한 조언이 있습니까?

열에서 NA 만 일치하는 dplyr을 사용하여 모든 변수가 NA 인 행 제거 에서 수정 하고 새 변수를 생성하지 않고 필터링합니다.

장난감 예 :

library(dplyr)
df <- tibble(a = c('a', 'a', 'a', NA), 
             b1 = c('b', 'c', NA, NA), 
             b2 = c('d', NA, NA, NA),
             b3 = c('e', NA, NA, NA),
             b4 = c('f', NA, NA, 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   

질문:

그러나 행 내에서 열 하위 집합이 문자열 일치 OR 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   

답변

1 akrun Aug 19 2020 at 02:58

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