観測ごとに複数の文字列を含むリストがあります(以下を参照)。
[1] A, C, D
[2] P, O, E
[3] W, E, W
[4] S, B, W
文字列に特定の部分文字列が含まれているかどうかをテストし、含まれている場合は、それぞれの部分文字列を返します。この例では、これは「A」または「B」のいずれかになります(以下の望ましい結果を参照)。各観測には、2つの部分文字列(A | B)のいずれか1つのみが含まれます。
[1] A
[2] NA
[3] NA
[4] B
いいえ、私はそれを解決するためにこの試みをしましたが、それは非常に非効率的であるように思われ、また私はそれを機能させることができません。どうすれば解決できますか?
if (i == "A") {
type <- "A"
} else if { (i == "B")
type <- "B"
} else { type <- "NA"
}
注:1000を超える観測値をループする必要があります
文字のベクトルがあると仮定すると、この目的でstringr::str_extract
を使用できます。
s <- c('A, C, D', 'P, O, E', 'W, E, W', 'S, B, W')
s
# [1] "A, C, D" "P, O, E" "W, E, W" "S, B, W"
stringr::str_extract(s, 'A|B')
# [1] "A" NA NA "B"
単語の一致が望ましい場合は、単語の境界を使用します\\b
:
stringr::str_extract(s, '\\b(A|B)\\b')
# [1] "A" NA NA "B"
部分文字列が", "
で定義されている場合は、次の正規表現(?<=^|, )(A|B)(?=,|$)
を使用できます。
# use the test case from G.Grothendieck
stringr::str_extract(c("A.A, C", "D, B"), '(?<=^|, )(A|B)(?=,|$)')
# [1] NA "B"
以下に、ストラップとベースのソリューションを示します。 strapply
ソリューションは非常に短いですが、一致する要素がターゲットの部分文字列である可能性がある場合は機能しません。ただし、これらは質問の部分文字列ではないため、そこで機能するはずです。基本ソリューションは、正規表現ではなく完全一致を使用するため、その場合でも機能します。
1)ストラップ(gsubfn) gsubfnでstrapply
を使用します。リストを出力する場合は、simplify=TRUE
を省略してください。 [AB]
は、必要に応じてA|B
に置き換えることができます。
library(gsubfn)
strapply(x, "[AB]", empty = NA, simplify = TRUE)
## [1] "A" NA NA "B"
2)base入力を分割し、分割の各要素について、リストL
を与える一致を除外します。 L
で十分な場合もありますが、そうでない場合は、最後の行でベクトルに簡略化され、長さゼロの要素がNAに置き換えられます。
L <- lapply(strsplit(x, ", "), Filter, f = function(x) x %in% c("A", "B"))
unlist(replace(L, !lengths(L), NA))
## [1] "A" NA NA "B"
x <- c("A, C, D", "P, O, E", "W, E, W", "S, B, W")
最終的にリストを作成したい場合は、次を使用できます。
library(magrittr)
x = list(
c("A", "C", "D"),
c("P", "O", "E"),
c("W", "E", "W"),
c("S", "B", "W")
)
myFunction <- function(x){
x1 <- paste0(x, collapse = "")
ifelse(stringr::str_detect(x1 , "A|B"), stringr::str_extract(x1, "A|B"), NA)
}
x %>% purrr::map(~ myFunction(.))
Base Rでは、文字列をループして検出し、[
および<-
([<-
)を使用して出力に割り当てることができます。
invec <- c(
'A, C, D',
'P, O, E',
'W, E, W',
'S, B, W')
out <- rep(NA, length(invec))
for(x in c('A', 'B')) out[grep(x, invec)] <- x
out
#[1] "A" NA NA "B"
パッケージを使用せず、ベクターのみを操作する場合:
vec <- c('A, C, D',
'P, O, E',
'W, E, W',
'S, B, W')
ifelse(grepl('A', vec), 'A', ifelse(grepl('B', vec), 'B', NA))
これをさらに単純化することもできますが、どのように機能するかを確認できるように、展開した形式のままにしておきました。