2014-08-30 86 views
3

我的目標是識別美國狀態,寫入包含其他文本的字符向量中,並將狀態轉換爲縮寫形式。例如,「北卡羅來納州」到「NC」。如果矢量只有長形式的名稱,這很簡單。但是,我的矢量在隨機的地方有其他文本,例如「states」。將使用其他文本嵌入的長狀態名轉換爲雙字母狀態縮寫

states <- c("Plano New Jersey", "NC", "xyz", "Alabama 02138", "Texas", "Town Iowa 99999") 

從另一個帖子,我發現這一點:

state.abb[match(states, state.name)] 

,但它僅轉換獨立德州

> state.abb[match(states, state.name)] 
[1] NA NA NA NA "TX" 

,而不是新澤西州,阿拉巴馬州和愛荷華州的字符串。

Fast grep with a vectored pattern or match, to return list of all matches我想:

sapply(states, grep(pattern = state.name, x = states, value = TRUE)) 

Error in get(as.character(FUN), mode = "function", envir = envir) : 
    object 'Alabama 02138' of mode 'function' was not found 
In addition: Warning message: 
In grep(pattern = state.name, x = states, value = TRUE) : 
    argument 'pattern' has length > 1 and only the first element will be used 

也不這項工作:

sapply(states, function(x) state.abb[grep(state.name, states)]) 

這個問題並沒有幫助: regular expression to convert state names to abbreviations

如何將嵌入式長名稱轉換爲州名縮寫?

編輯:我想返回矢量,唯一的變化就是縮短了州名的長名,例如「Plano New Jersey」變成「Plano NJ」。

感謝您糾正和/或教育我。

+0

你可能會得到'NY,NY',再加上有些城鎮叫做'California'以及州。但是,這是挑剔的你。 – 2014-08-30 14:02:05

+0

@Jonathan Leffler:是的,所謂的州稱爲職業危害。另外我有不止一個州的城市。嘆。爲什麼數據不能很好地表現? – lawyeR 2014-08-30 14:07:45

+0

有一件名爲「真實世界」的東西,你應該訪問某個時間(「親愛的壺 - 你是黑色!簽名,壺」)。它與我們編寫程序的人設計的整潔計劃有着不同的習慣。 – 2014-08-30 14:16:42

回答

3

這裏的另一種方法:

library(qdap) 
mgsub(state.name, state.abb, states) 

## [1] "Plano NJ"  "NC"   "xyz"   "AL 02138"  
## "TX"   "Town IA 99999" 

如果你不能確定的是,國家將予以資本化,你可能要使用:

mgsub(state.name, state.abb, states, ignore.case=TRUE, fixed=FALSE) 
3

嘗試:

indx <- paste0(".*(", paste(state.name, collapse="|"), ").*") 
v1 <- gsub(indx, "\\1", states) 
ifelse(v1 %in% state.abb, v1, state.abb[match(v1, state.name)]) 
#[1] "NJ" "NC" NA "AL" "TX" "IA" 

如果你想只用縮寫,而不是其他的文本替換狀態,你也可以這樣做:

indx1 <- paste(state.name, collapse="|") 
indx2 <- state.abb[match(v1, state.name)] 

mapply(gsub, indx1, indx2, states, USE.NAMES=F) 
#[1] "Plano NJ"  "NC"   "xyz"   "AL 02138"  
#[5] "TX"   "Town IA 99999" 
+0

我注意到這會用alfabet中第一個狀態的縮寫代替每個匹配狀態。例如,輸入「Texas Alabama」將導致「AL AL」。有沒有辦法避免這種情況? – ebo 2014-08-30 16:40:10

+0

@EricBouwers在OP提供的例子中,情況並非如此。所以,我沒有這樣檢查 – akrun 2014-08-30 17:46:14

1

它不是從問題不清楚是什麼預期的結果是,但在這裏我們假設你想要保留輸入中的文本,只需用縮寫代替fuil狀態名稱即可。

創建一個列表,st,其名稱是完整的狀態名稱,其值是縮寫。然後使用paste(..., collapse = "|")創建一個匹配任何狀態的正則表達式,並使用gsubfn包中的gsubfn來執行替換。

library(gsubfn) 
st <- as.list(setNames(state.abb, state.name)) 
gsubfn(paste(state.name, collapse = "|"), st, states) 

,並提供:

[1] "Plano NJ"  "NC"   "xyz"   "AL 02138"  
[5] "TX"   "Town IA 99999" 
1

如果你不想使用額外的包,你可以使用mapply功能申請gsub所有對state.namestate.abb,例如:

mapply(gsub,state.name,state.abb,"ALABAMA 123",ignore.case=TRUE,USE.NAMES=FALSE) 

這樣做的結果是可能包含更換的列表,例如:

[1] "AL 123"  "ALABAMA 123" "ALABAMA 123" "ALABAMA 123" "ALABAMA 123" 
[6] ... 

採取從該列表中最短的文字就可以得到想要的結果。因此我們sort the list based on the length of the text並採取第一個元素。

的完整代碼:

replaceState <- function(x) { 
    v = mapply(gsub,state.name,state.abb,x,ignore.case=TRUE, USE.NAMES=FALSE) 
    v[order(nchar(v))][1] 
} 

sapply(states, replaceState, USE.NAMES=FALSE) 

不幸的是,這種方法只替換一個單一的國家(最長)的名稱。要更換,我們需要遍歷多個不同的狀態,例如:

replaceState <- function(x) { 
    v = mapply(gsub,state.name,state.abb,x,ignore.case=TRUE, USE.NAMES=FALSE) 
    v[order(nchar(v))][1] 
} 

replaceStates <- function(x) { 
    newX = replaceState(x) 

    # if they are different a state has been replaced, 
    # we try again to replace all states. 
    if(newX != x){ 
      replaceStates(newX) 
    } else { 
      newX 
    } 
} 

# Note the 'replaceStates' 
sapply(states, replaceStates, USE.NAMES=FALSE) 
0

嘗試:

for(r in 1:nrow(states.list)) { 
    states = gsub(states.list[r,1], states.list[r,2], states) 
} 

states 
[1] "Plano NJ"  "NC"   "xyz"   "AL 02138"  "TX"   "Town IA 99999" 

數據:

states <- c("Plano New Jersey", "NC", "xyz", "Alabama 02138", "Texas", "Town Iowa 99999") 

states.list = structure(list(state.name = structure(c(4L, 1L, 5L, 2L, 3L), .Label = c("Alabama", 
"Iowa", "Minnesota", "New Jersey", "Texas"), class = "factor"), 
    state.abb = structure(c(4L, 1L, 5L, 2L, 3L), .Label = c("AL", 
    "IA", "MN", "NJ", "TX"), class = "factor")), .Names = c("state.name", 
"state.abb"), class = "data.frame", row.names = c(NA, -5L)) 

states.list 
    state.name state.abb 
1 New Jersey  NJ 
2 Alabama  AL 
3  Texas  TX 
4  Iowa  IA 
5 Minnesota  MN