2017-10-05 31 views
2

文字列とPOSタグを含むデータ名があります。特定のPOSタグをフィルタリングして特定の文字列を抽出したい。正規表現を使用して特定の文字列を抽出する

単純な例として、「NN-NN-NN」と「VB-JJ-NN」の文字列を抽出します。

df <- data.frame(word = c("abrasion process management", 
          "slurries comprise abrasive", 
          "slurry compositions comprise ", 
          "keep high polishing", 
          "improved superabrasive grit", 
          "using ceriacoated silica", 
          "and grinding", 
          "for cmp", 
          "and grinding for"), 
       pos_tag = c("NN-NN-NN", "NNS-NN-NN", "NN-NNS-NN", "VB-JJ-NN", 
          "VBN-JJ-NN", "VBG-JJ-NN", "CC-VBG", "IN-NN", "CC-VBG-IN")) 

> df 
       word    pos_tag 
1 abrasion process management NN-NN-NN 
2 slurries comprise abrasive NNS-NN-NN 
3 slurry compositions comprise NN-NNS-NN 
4   keep high polishing VB-JJ-NN 
5 improved superabrasive grit VBN-JJ-NN 
6  using ceriacoated silica VBG-JJ-NN 
7     and grinding CC-VBG 
8      for cmp IN-NN 
9    and grinding for CC-VBG-IN 

私のパターンを定義するために正規表現を使用しようとしました。 しかし、それはパターンを定義する効率的な方法ではないと思います。 他のより効率的な方法がありますか?ここ

pos <- c("NN-NN-NN", "NNS-NN-NN", "NN-NNS-NN", "VB.-JJ-NN", "VB-JJ-NN") 
pos2 <- paste0('^', pos , "\\w*$", collapse = '|') 
sort_string <- df[grep(pos2, df$pos_tag),] %>% 
       unique() 

は、私はあなたがそのための正規表現を必要としない

   word    pos_tag 
1 abrasion process management NN-NN-NN 
2 slurries comprise abrasive NNS-NN-NN 
3 slurry compositions comprise NN-NNS-NN 
4   keep high polishing VB-JJ-NN 
5 improved superabrasive grit VBN-JJ-NN 
6  using ceriacoated silica VBG-JJ-NN 
+0

期待されているのは 'NNS-NN-NN'です。パターンは明確ではありません – akrun

+0

質問はあまり明確ではありません。私が理解しているかどうかを見てみましょう:単語から "i"要素を取り出し、それをpos_tagの "i"要素に一致させ、ファイル/コンソールに1から "i" i "はループ・インデックス・コントロールの略です。また、行番号を印刷することもできます。これはあなたが欲しいものですか? – Heto

答えて

2

を取得したいものです。

vec <- c("NN-NN-NN", "VB-JJ-NN") 

library(stringdist) 
df[!!amatch(df$pos_tag, vec, maxDist = 1, nomatch = 0),] 

います:

      word pos_tag 
1 abrasion process management NN-NN-NN 
2 slurries comprise abrasive NNS-NN-NN 
3 slurry compositions comprise NN-NNS-NN 
4   keep high polishing VB-JJ-NN 
5 improved superabrasive grit VBN-JJ-NN 
6  using ceriacoated silica VBG-JJ-NN 

を、これは何:可能性がstringdist -packageからamatch -functionを使用することです

  • amatch(df$pos_tag, vec, maxDist = 1, nomatch = 0)df$pos_tagの値が一致するかどうかに見える

    差異の指定された許容差を持つvecの値。この場合
  • 私は、1つの文字の最大許容editdistance使用:あなたはpos_tagているかどうかを示す論理ベクトルを作成!!、二重否定することでmaxDist = 1
  • を(ほぼ)VECでの値のいずれかと一致します。代替は次のとおりです。df[amatch(df$pos_tag, vec, maxDist = 1, nomatch = 0) > 0,]

あなたはまた、sapply/lapplyrowSums/unlistと組み合わせてagrep/agreplをベースRでこれを行うことができます:

# method 1: 
df[rowSums(sapply(vec, function(x) agrepl(x, df$pos_tag, max.distance = 1))) > 0,] 

# method 2: 
df[unlist(lapply(vec, function(x) agrep(x, df$pos_tag, max.distance = 1))),] 

両方があなたに同じを与えます結果。

+0

wow〜これは本当に効率的な方法です。私は私のプロセスでこの方法を使用しています。しかしそれは別の問題を示しています。私のデータの名声には「IN-NN-NN」、「VB-RB-IN」、「NN-IN-NN」posタグなどもあるからです。 (申し訳ありませんが私の例のdfにすべてのposタグを表示していませんでした)。だから私はamatch()を使用するときにも、私は欲しくない他のパターンを抽出します。 – Eva

+0

@Evaそれはどれくらいの「偽」の一致に依存しますが、%cの '!df $ pos_tag%(" IN-NN-NN "、" VB-RB- IN "、" NN-IN-NN ")' – Jaap

関連する問題