web-dev-qa-db-ja.com

文字列にRの部分文字列が含まれているかどうかを確認するifelseステートメント

観測ごとに複数の文字列を含むリストがあります(以下を参照)。

  [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を超える観測値をループする必要があります

3
Carolin

文字のベクトルがあると仮定すると、この目的で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"
3
Psidom

以下に、ストラップとベースのソリューションを示します。 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")
1
G. Grothendieck

最終的にリストを作成したい場合は、次を使用できます。

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(.))
0
TBT8

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"
0
IceCreamToucan

パッケージを使用せず、ベクターのみを操作する場合:

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

これをさらに単純化することもできますが、どのように機能するかを確認できるように、展開した形式のままにしておきました。

0
Gautam