パターンに従って部分文字列を抽出する


136

文字列のリストがあるとします。

string = c("G1:E001", "G2:E002", "G3:E003")

ここで、コロン「:」の後の部分のみを含む文字列のベクトルを取得したいと考えていますsubstring = c(E001,E002,E003)

Rでこれを行う便利な方法はありますか?使い方substr

回答:


238

ここにいくつかの方法があります:

1)サブ

sub(".*:", "", string)
## [1] "E001" "E002" "E003"

2)strsplit

sapply(strsplit(string, ":"), "[", 2)
## [1] "E001" "E002" "E003"

3)read.table

read.table(text = string, sep = ":", as.is = TRUE)$V2
## [1] "E001" "E002" "E003"

4)サブストリング

これは、2番目の部分が常に4番目の文字で始まると想定しています(問題の例の場合)。

substring(string, 4)
## [1] "E001" "E002" "E003"

4a)サブストリング/正規表現

コロンが常に既知の位置にあるとは限らなかった場合、それを検索することで(4)を変更できます。

substring(string, regexpr(":", string) + 1)

5)ストラップ

strapplyc 括弧で囲まれた部分を返します:

library(gsubfn)
strapplyc(string, ":(.*)", simplify = TRUE)
## [1] "E001" "E002" "E003"

6)read.dcf

これは、コロンの前の部分文字列が一意である場合にのみ機能します(問題の例にあります)。また、セパレーターはコロンである必要があります(これは問題です)。別のセパレータが使用されている場合は、それをsub最初にコロンに置き換えるために使用できます。例えば、セパレータがあった場合は_、その後string <- sub("_", ":", string)

c(read.dcf(textConnection(string)))
## [1] "E001" "E002" "E003"

7)分離する

7a)を使用しtidyr::separateて、2つの列を持つデータフレームを作成します。1つはコロンの前の部分、もう1つは後の列で、後者を抽出します。

library(dplyr)
library(tidyr)
library(purrr)

DF <- data.frame(string)
DF %>% 
  separate(string, into = c("pre", "post")) %>% 
  pull("post")
## [1] "E001" "E002" "E003"

7b)またはseparatepost列を作成してunlistからunname、結果のデータフレームを作成することもできます。

library(dplyr)
library(tidyr)

DF %>% 
  separate(string, into = c(NA, "post")) %>% 
  unlist %>%
  unname
## [1] "E001" "E002" "E003"

8)trimwsを使用trimwsして、単語の文字を左側からトリミングしてから、それを再度使用してコロンをトリミングできます。

trimws(trimws(string, "left", "\\w"), "left", ":")
## [1] "E001" "E002" "E003"

注意

入力stringは次のように想定されています。

string <- c("G1:E001", "G2:E002", "G3:E003")

私が持っていたことを、溶融したテーブル内の変数を持っていた_セパレータとしてとするための2つの別々の変数を作った接頭辞と接尾辞@Grothendieckの回答に基づいて: prefix <- sub("_.*", "", variable)suffix <- sub(".*_", "", variable)
swihart

この素晴らしい答えのマイクロベンチマークを見るのは素晴らしいことです!
1

25

たとえば、gsubまたはsub

    gsub('.*:(.*)','\\1',string)
    [1] "E001" "E002" "E003"

これらを説明できますか?*(*などは正確にありますか?わずかに異なる設定でこれを再作成するのに苦労しています...
Peter Pan

1
@PeterPanコロンの後に表示される文字のグループをキャプチャして返します。照合する文字列がより複雑で、ベースRにとどまりたい場合、これはうまく機能します。
クラークフィッツジェラルド


9

パーティーには遅れますが、後世のために、ストリンガーパッケージ(人気のある「tidyverse」パッケージスイートの一部)は、文字列処理のための調和された署名を持つ関数を提供します。

string <- c("G1:E001", "G2:E002", "G3:E003")
# match string to keep
stringr::str_extract(string = string, pattern = "E[0-9]+")
# [1] "E001" "E002" "E003"

# replace leading string with ""
stringr::str_remove(string = string, pattern = "^.*:")
# [1] "E001" "E002" "E003"

2
これは、コロンの後のすべてではなく、Eで始まる最初の数字を見つけたのではないですか?
マークニール


3

あなたが使用しているならdata.table、それtstrsplit()は自然な選択です:

tstrsplit(string, ":")[[2]]
[1] "E001" "E002" "E003"

3

unglueパッケージは代替手段を提供し、正規表現についての知識が簡単な場合のために必要とされない、ここで私たちは思います。

# install.packages("unglue")
library(unglue)
string = c("G1:E001", "G2:E002", "G3:E003")
unglue_vec(string,"{x}:{y}", var = "y")
#> [1] "E001" "E002" "E003"

reprexパッケージ(v0.3.0)によって2019-11-06に作成されました

詳細:https : //github.com/moodymudskipper/unglue/blob/master/README.md

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.