September 26, 2016

為甚麼要字串處理?

  • 資料清理
  • 截取文字資料
  • 不知道完整名稱

常用function

  • grep
  • grepl
  • regexpr
  • sub
  • gsub
  • substr

Data:

鄉鎮市區 交易標的 土地區段位置.建物區段門牌
文山區 房地(土地+建物) 臺北市文山區指南路二段91~120號
大同區 房地(土地+建物) 臺北市大同區重慶北路一段61~90號
文山區 房地(土地+建物) 臺北市文山區指南路三段1~30號
文山區 房地(土地+建物) 臺北市文山區指南路二段45巷31~60號
內湖區 房地(土地+建物) 臺北市內湖區民權東路六段90巷6弄1~30號
文山區 房地(土地+建物) 臺北市文山區興隆路四段1~30號

Example:

(address = as.character(address)) 
## [1] "臺北市文山區指南路二段91~120號"       
## [2] "臺北市大同區重慶北路一段61~90號"      
## [3] "臺北市文山區指南路三段1~30號"         
## [4] "臺北市文山區指南路二段45巷31~60號"    
## [5] "臺北市內湖區民權東路六段90巷6弄1~30號"
## [6] "臺北市文山區興隆路四段1~30號"

grep

grep第一個參數是pattern, 第二個是data,

output為符合這個pattern是第幾筆資料

grep(pattern = "文山區", x = address)
## [1] 1 3 4 6
grep("指南路", address)
## [1] 1 3 4
grep("指南路二段", address)
## [1] 1 4

grep

(a1 = grep("指南路二段", address))
## [1] 1 4
address[a1]
## [1] "臺北市文山區指南路二段91~120號"    "臺北市文山區指南路二段45巷31~60號"

grepl

與grep類似,但output是TRUE/FALSE

grepl(pattern = "文山區", x = address)
## [1]  TRUE FALSE  TRUE  TRUE FALSE  TRUE
grepl("指南路", address)
## [1]  TRUE FALSE  TRUE  TRUE FALSE FALSE
grepl("指南路二段", address)
## [1]  TRUE FALSE FALSE  TRUE FALSE FALSE

grepl

(a1 = grepl("指南路二段", address))
## [1]  TRUE FALSE FALSE  TRUE FALSE FALSE
address[a1]
## [1] "臺北市文山區指南路二段91~120號"    "臺北市文山區指南路二段45巷31~60號"

regexpr

找出符合pattern的字串在哪個位置及長度,

如果不符合pattern,會顯示-1

## [1] "臺北市文山區指南路二段91~120號"       
## [2] "臺北市大同區重慶北路一段61~90號"      
## [3] "臺北市文山區指南路三段1~30號"         
## [4] "臺北市文山區指南路二段45巷31~60號"    
## [5] "臺北市內湖區民權東路六段90巷6弄1~30號"
## [6] "臺北市文山區興隆路四段1~30號"
regexpr(pattern = "指", text = address)
## [1]  7 -1  7  7 -1 -1
## attr(,"match.length")
## [1]  1 -1  1  1 -1 -1

regexpr

regexpr(pattern = "指南路", text = address)
## [1]  7 -1  7  7 -1 -1
## attr(,"match.length")
## [1]  3 -1  3  3 -1 -1
regexpr("指南路二段", address)
## [1]  7 -1 -1  7 -1 -1
## attr(,"match.length")
## [1]  5 -1 -1  5 -1 -1

regexpr

regexpr("號", address)
## [1] 18 18 16 20 22 16
## attr(,"match.length")
## [1] 1 1 1 1 1 1
regexpr("[0-9]", address)
## [1] 12 13 12 12 13 12
## attr(,"match.length")
## [1] 1 1 1 1 1 1

sub

sub指substitute,把每個字串中第一個符合pattern的內容取代

sub(pattern = "指南路", replacement = "AAA", x = address)
## [1] "臺北市文山區AAA二段91~120號"          
## [2] "臺北市大同區重慶北路一段61~90號"      
## [3] "臺北市文山區AAA三段1~30號"            
## [4] "臺北市文山區AAA二段45巷31~60號"       
## [5] "臺北市內湖區民權東路六段90巷6弄1~30號"
## [6] "臺北市文山區興隆路四段1~30號"

sub

sub("[0-9]", "X", address)
## [1] "臺北市文山區指南路二段X1~120號"       
## [2] "臺北市大同區重慶北路一段X1~90號"      
## [3] "臺北市文山區指南路三段X~30號"         
## [4] "臺北市文山區指南路二段X5巷31~60號"    
## [5] "臺北市內湖區民權東路六段X0巷6弄1~30號"
## [6] "臺北市文山區興隆路四段X~30號"

gsub

把每個字串中所有符合pattern的內容取代

gsub(pattern = "指南路", replacement = "AAA", x = address)
## [1] "臺北市文山區AAA二段91~120號"          
## [2] "臺北市大同區重慶北路一段61~90號"      
## [3] "臺北市文山區AAA三段1~30號"            
## [4] "臺北市文山區AAA二段45巷31~60號"       
## [5] "臺北市內湖區民權東路六段90巷6弄1~30號"
## [6] "臺北市文山區興隆路四段1~30號"

gsub

gsub("[0-9]","X",address)
## [1] "臺北市文山區指南路二段XX~XXX號"       
## [2] "臺北市大同區重慶北路一段XX~XX號"      
## [3] "臺北市文山區指南路三段X~XX號"         
## [4] "臺北市文山區指南路二段XX巷XX~XX號"    
## [5] "臺北市內湖區民權東路六段XX巷X弄X~XX號"
## [6] "臺北市文山區興隆路四段X~XX號"

substr

回想工作坊,如果我只要行政區與路段

substr(address, start = 4, stop = 12)
## [1] "文山區指南路二段9"  "大同區重慶北路一段" "文山區指南路三段1" 
## [4] "文山區指南路二段4"  "內湖區民權東路六段" "文山區興隆路四段1"

substr

結合regexpr

(a1 = regexpr("[0-9]",address))
## [1] 12 13 12 12 13 12
## attr(,"match.length")
## [1] 1 1 1 1 1 1
(a2 = regexpr("號",address))
## [1] 18 18 16 20 22 16
## attr(,"match.length")
## [1] 1 1 1 1 1 1

substr

substr(x = address, start = a1, stop = a2)
## [1] "91~120號"      "61~90號"       "1~30號"        "45巷31~60號"  
## [5] "90巷6弄1~30號" "1~30號"
substr(address, a1, nchar(address))
## [1] "91~120號"      "61~90號"       "1~30號"        "45巷31~60號"  
## [5] "90巷6弄1~30號" "1~30號"

substr

substr(address, 4, a1)
## [1] "文山區指南路二段9"   "大同區重慶北路一段6" "文山區指南路三段1"  
## [4] "文山區指南路二段4"   "內湖區民權東路六段9" "文山區興隆路四段1"
substr(address, 4, a1-1)
## [1] "文山區指南路二段"   "大同區重慶北路一段" "文山區指南路三段"  
## [4] "文山區指南路二段"   "內湖區民權東路六段" "文山區興隆路四段"

雜談

  • 方法有很多種
  • 找出字串規律

參考資源