2013-07-07 29 views
8

Tôi đang xử lý một lượng lớn dữ liệu, chủ yếu là các tên có ký tự không phải tiếng Anh. Mục tiêu của tôi là để phù hợp với những tên này chống lại một số thông tin về họ thu thập được ở Mỹ.R: Thay thế các ký tự nước ngoài bằng một chuỗi

nghĩa là tôi có thể khớp tên 'Sølvsten' (từ một số danh sách tên) với 'Soelvsten' (tên được lưu trữ trong một số cơ sở dữ liệu của Mỹ). Đây là một chức năng tôi đã viết để làm điều này. Đó là rõ ràng clunky và hơi tùy ý, nhưng tôi tự hỏi, nếu có một chức năng R đơn giản mà dịch các ký tự nước ngoài để hàng xóm tiếng Anh gần nhất của họ. Tôi hiểu rằng có thể không có cách nào tiêu chuẩn để thực hiện chuyển đổi này, nhưng tôi chỉ tò mò nếu có và nếu chuyển đổi đó có thể được thực hiện thông qua chức năng R.

# a function to replace foreign characters 
replaceforeignchars <- function(x) 
{ 
    require(gsubfn); 
    x <- gsub("š","s",x) 
    x <- gsub("œ","oe",x) 
    x <- gsub("ž","z",x) 
    x <- gsub("ß","ss",x) 
    x <- gsub("þ","y",x) 
    x <- gsub("à","a",x) 
    x <- gsub("á","a",x) 
    x <- gsub("â","a",x) 
    x <- gsub("ã","a",x) 
    x <- gsub("ä","a",x) 
    x <- gsub("å","a",x) 
    x <- gsub("æ","ae",x) 
    x <- gsub("ç","c",x) 
    x <- gsub("è","e",x) 
    x <- gsub("é","e",x) 
    x <- gsub("ê","e",x) 
    x <- gsub("ë","e",x) 
    x <- gsub("ì","i",x) 
    x <- gsub("í","i",x) 
    x <- gsub("î","i",x) 
    x <- gsub("ï","i",x) 
    x <- gsub("ð","d",x) 
    x <- gsub("ñ","n",x) 
    x <- gsub("ò","o",x) 
    x <- gsub("ó","o",x) 
    x <- gsub("ô","o",x) 
    x <- gsub("õ","o",x) 
    x <- gsub("ö","o",x) 
    x <- gsub("ø","oe",x) 
    x <- gsub("ù","u",x) 
    x <- gsub("ú","u",x) 
    x <- gsub("û","u",x) 
    x <- gsub("ü","u",x) 
    x <- gsub("ý","y",x) 
    x <- gsub("ÿ","y",x) 
    x <- gsub("ğ","g",x) 

    return(x) 
} 

Lưu ý: Tôi biết có tồn tại các thuật toán khớp tên như Jaro Winkler Distance Matching, nhưng tôi muốn thực hiện các kết hợp chính xác.

Trả lời

16

Hãy thử sử dụng chức năng chartr R cho một thay thế ký tự (nhanh hơn) và sau đó làm sạch bằng một chuỗi các cuộc gọi gsub cho mỗi thay thế ký tự một (có thể sẽ chậm hơn) nhưng không có nhiều người trong số họ).

to.plain <- function(s) { 

    # 1 character substitutions 
    old1 <- "šžþàáâãäåçèéêëìíîïðñòóôõöùúûüý" 
    new1 <- "szyaaaaaaceeeeiiiidnooooouuuuy" 
    s1 <- chartr(old1, new1, s) 

    # 2 character substitutions 
    old2 <- c("œ", "ß", "æ", "ø") 
    new2 <- c("oe", "ss", "ae", "oe") 
    s2 <- s1 
    for(i in seq_along(old2)) s2 <- gsub(old2[i], new2[i], s2, fixed = TRUE) 

    s2 
} 

Thêm vào old1, new1, old2new2 khi cần thiết.

Dưới đây là một thử nghiệm:

> s <- "æxš" 
> to.plain(s) 
[1] "aexs" 

UPDATE: sửa tên biến trong chartr.

+0

Cảm ơn, Gabor (tôi giả sử bạn cũng giống như http://r.789695.n4.nabble.com/template/NamlServlet.jtp?macro=user_nodes&user=39147). Tôi đã thử nghiệm cả ba giải pháp được đăng cho đến nay và điều này có vẻ nhanh nhất (mặc dù, tôi chỉ quan sát thời gian thực hiện và không thực sự ** thời gian **, _and_ trên máy tính xách tay không được cắm vào để biết điều gì đang thúc đẩy hiệu quả :-)) – krishnan

+0

không nên là 's1 <- chatr (old1, new1, s)'? – Lucarno

+0

Cảm ơn. Vâng. Đã sửa lỗi. –

7

Bạn có thể cài đặt chương trình uni2ascii C và gọi nó là từ R.

uni2ascii <- function(string) { 
    cmd <- sprintf("echo %s | uni2ascii -B", string) 
    system(cmd, intern = TRUE, ignore.stderr = TRUE) 
} 

uni2ascii <- Vectorize(uni2ascii, USE.NAMES = FALSE) 

uni2ascii(c("Sølvsten", "ğ", "œ")) 
## [1] "Solvsten" "g"  "oe" 
7

Sửa cho một kết quả có khả năng tốt hơn ...

Điều này có thể không làm việc cho tất cả các trường hợp, nhưng iconv sức có giá trị điều tra. Từ ?iconv:

Mô tả:

This uses system facilities to convert a character vector between 
encodings: the ‘i’ stands for ‘internationalization’. 

Ví dụ:

test <- c("Sølvsten", "Günther") 
iconv(test, "latin1", "ASCII//TRANSLIT") 
#[1] "Solvsten" "Gunther" 

Đây không phải là vô cùng đơn giản, nhưng tôi nghĩ rằng có cái gì đó để nói cho tách dữ liệu từ mã.Điều này sau đó rất giống với câu hỏi này:

R: replace characters using gsub, how to create a function?

Xác định từ và đến:

fromto <- read.table(text=" 
from to 
š s 
œ oe 
ž z 
ß ss 
þ y 
à a 
á a 
â a 
ã a 
ä a 
å a 
æ ae 
ç c 
è e 
é e 
ê e 
ë e 
ì i 
í i 
î i 
ï i 
ð d 
ñ n 
ò o 
ó o 
ô o 
õ o 
ö o 
ø oe 
ù u 
ú u 
û u 
ü u 
ý y 
ÿ y 
ğ g",header=TRUE) 

Sau đó các chức năng:

replaceforeignchars <- function(dat,fromto) { 
    for(i in 1:nrow(fromto)) { 
    dat <- gsub(fromto$from[i],fromto$to[i],dat) 
    } 
    dat 
} 

test <- c("Sølvsten", "Günther") 
replaceforeignchars(test,fromto) 
#[1] "Soelvsten" "Gunther" 
+0

Ý tưởng hay về tách dữ liệu khỏi mã. – asb

0

Mở rộng câu trả lời của thelatemail: Bản gốc Hàm replaceforeignchars chứa một vòng lặp, có thể tiêu thụ tài nguyên cho các văn bản lớn. Đây là một hàm áp dụng giống hệt nhau mà không có vòng lặp rõ ràng. Khi nó đứng, nó hoạt động cho một chuỗi đơn (ví dụ: không phải là chuỗi vectơ).

replaceforeignchars <- function(dat,fromto) { 
    paste0(apply(matrix(unlist(strsplit(dat,""))),1,FUN=function(x) {ifelse(x %in% fromto$from, as.character(fromto[fromto$from==x, 'to']), x)}), collapse="") 
} 
test <- c("Sølvsten") 
replaceforeignchars(test,fromto) 
[1] "Solvsten" 
Các vấn đề liên quan