2017-04-06 5 views
1

grepを使用していくつかのアドレスデータを整理しています。ここでの目標は特定のレコードと列の通り/道/道路名などです、すでに次の変数tempval、例えば、個々の単語にスペースによって分割された:私は、通りの名前に続く単語のいくつかがあるかもしれない場所を見つけるために、次のステートメントを使用しR:grepを使用して重要度の順に1つまたは複数の一致を見つけよう

R > tempval 
[1] "38" "WILLOW" "PARK" 

stID <- grep("STREET|\\bST\\b|AVENUE|\\bAVE\\b|\\bAV\\b|WAY|BOULEVARD|\\bBD\\b|ROAD|\\bRD\\b|PLACE|\\bPL\\b|ESPLANADE|TERRACE|PARADE|DRIVE|\\bDR\\b|\\bPARK\\b|LANE|CRESCENT|\\bCOURT\\b|b\\CRES\\b", tempval, ignore.case = T) 

R > stID 
[1] 3 

Th大丈夫です、私は "公園"が3番目の要素であることを知っています、それは私の通り番号と名前になる前に来るものです。

しかし問題は、例えば、いくつかのマッチそうlength(stID) > 1が存在する場合に生じる:だからここ

R > tempval 
[1] "38" "PARK" "ST" 

、私は中、Rは、一つだけの一致を返してもらうにはどうすればよい

R > stID 
[1] 2 3 

を取得します重要度の順序(grepのパターンで文字列を配置した順序)言い換えれば、Rが "ST"と "PARK"の両方を見つけた場合、 "ST"が "PARK"よりも重要であるので、stID = 3だけを返しますか?

答えて

3

grepを使用すると、あなたのgrepは、「streetlife Park」で試してみると、street-nameとして「streetlife」を返すようになっても(非常に危険です。ストリートライフ ")。

代わりにmatchを使用することをおすすめします。すべてをより低いものに変換し、重要度の順に値を持つベクトルを使用します。次にmatchを使用して、xのどの位置にそのベクトルと一致するものがあるかを確認できます。今、あなたはNAない最初の値を見ていると、あなたが行っている:

checkstreet <- function(x){ 
    x <- tolower(x) 
    thenames <- c("street","st","avenue","ave","av", 
       "way","boulevard", "bd", "road", "rd", 
       "place", "pl", "esplanade","terrace","parade", 
       "drive","dr","park","lane","crescent","court", 
       "cres") 

    id <- match(thenames, x) 
    id[!is.na(id)][1] 
} 

することはできます:あなたはグレップを使用して主張し、あなたの言葉のための\\bを使用し続ける場合は

> tmpval <- c("38","park","street") 
> checkstreet(tmpval) 
[1] 3 
> tmpval <- c("44","Average","Esplanade") 
> checkstreet(tmpval) 
[1] 3 

境界は、あなたが同じロジックを使用することができますが、今回はwhich.minを使用して:

checkstreet <- function(x){ 
    x <- tolower(x) 
    thenames <- c("street","st","avenue","ave","av", 
       "way","boulevard", "bd", "road", "rd", 
       "place", "pl", "esplanade","terrace","parade", 
       "drive","dr","park","lane","crescent","court", 
       "cres") 

    which.min(lapply(x,grep,thenames)) 
} 
+0

非常に良い、ありがとう! grepが心に浮かぶ最初のツールでしたが、重要な順番で文字列のベクトルとのマッチを使用することは完全に意味があります。 – Neodyme

1

あなたは検索語のindividuaのそれぞれを照合することによって、それを行うことができますあなたの検索リストの前に配置されているマッチに高いスコアを与えます:

## Vector of search terms: 
matchVec <- strsplit("STREET|\\bST\\b|AVENUE|\\bAVE\\b|\\bAV\\b|WAY|BOULEVARD|\\bBD\\b|ROAD|\\bRD\\b|PLACE|\\bPL\\b|ESPLANADE|TERRACE|PARADE|DRIVE|\\bDR\\b|\\bPARK\\b|LANE|CRESCENT|\\bCOURT\\b|b\\CRES\\b", "\\|")[[1]] 

## Function to determine score of the match: 
scoreMatch <- function(myString, matchVec){ 
    ## Position of matches in the search list: 
    position <- which(vapply(matchVec, function(matchStr) grepl(pattern = matchStr, x = myString), 
        logical(1))) 
    ## Score: First search term gets the highest score, second gets second 
    ## highest score etc. No match = score 0: 
    score <- ifelse(length(position) > 0, length(matchVec) - position + 1, 0) 
} 

## Determine score of each element/word in your vector: 
scoreVec <- vapply(tempval, function(x) scoreMatch(x, matchVec), numeric(1)) 

## Find index with the highest score: 
stID <- which.max(scoreVec) 
+0

私はあなたがここで何をしようとしているのかを見ていますが、実際に 'lapply'と' which.min'を使ってコードの1行で行うことができます(私の答えを参照してください) –

+0

はい、あなたの解決策は非常にエレガントです。しかし、 'checkstreet'(' grep'-version)の定義の最後の行は 'which.min(lapply(x、grep、thenames))'でしょうか? – ikop

+0

良いキャッチ、thx! –

関連する問題