列のサブセット全体で一致する文字列または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
質問:
ただし、行内の場合、列のサブセットが文字列一致ORNA
である場合、変数を作成する方法がわかりません。たとえば、'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