2012-02-10 16 views
9

Mam problemy z obsługą unikalnych znaków Unicode w R, szczególnie tych napotkanych podczas pobierania informacji z MediaWiki API. Chciałbym znaleźć ciąg JSON jakJak poprawnie radzić sobie ze zmienionymi znakami Unicode w R, np. the em dash (-)

{"query":{"categorymembers":[{"ns":0,"title":"Banach\u2013Tarski paradox"}]}} 

które powinny być całkowicie poprawny, ale gdy odczytywane przez fromJSON() uzyskać:

snip... 
[1] "Banach\023Tarski paradox" 

Początkowo myślałem, że to był tylko problem z RJSONIO, ale spotkać podobny problemy z scan() i readLines(). Domyślam się, że brakuje mi czegoś bardzo prostego.

Nie mogę podać całkowicie odtwarzalnego przykładu używając tylko R, ponieważ jeśli wyślę "em \ u2013dash" do pliku poprzez write() (lub jakąś równoważną funkcję) R automatycznie konwertuje ekran em. Więc idzie. Utwórz plik tekstowy o nazwie test1 z następujących czynności:

"em\u2013dash" "em–dash" " em \u2013 dash" 

Następnie załadować R (niezależnie ścieżka pliku jest):

> scan(file = "~/R/test1", what = "character", encoding = "UTF-8") 
Read 3 items 
[1] "em\\u2013dash" "em–dash"   " em \\u2013 dash" 
> readLines("~/R/test1", warn = FALSE, encoding = "UTF-8") 
[1] "\"em\\u2013dash\" \"em–dash\" \" em \\u2013 dash\"" 

Dodana postać ucieczka, co powoduje moje problemy z fromJSON(). Mogłem po prostu je rozebrać, ale prawdopodobnie zepsułbym coś jeszcze w tym procesie i wyobrażam sobie, że jest łatwiejsze rozwiązanie. Dzięki.

Oto info sesja:

R version 2.14.1 (2011-12-22) 
Platform: x86_64-apple-darwin9.8.0/x86_64 (64-bit) 

locale: 
[1] C/en_US.UTF-8/C/C/C/C 

attached base packages: 
[1] stats  graphics grDevices utils  datasets methods base  

other attached packages: 
[1] RJSONIO_0.98-0 

loaded via a namespace (and not attached): 
[1] tools_2.14.1 
+0

Jeśli zastosujemy się do wiadomości w '' scan' dotyczących allowEscapes? 'argument do'? Quotes', sugeruje, że parser po prostu nie obsługuje tego w 'scan'. Ale wydaje mi się to dziwne, więc mam nadzieję, że się mylę. – joran

+0

Tak, też to widziałem (bit z "? Quotes"). Otrzymuję również ten sam wynik odczytu w treści od readLines przez połączenie lub od 'getURL()' w RCurl bezpośrednio. –

Odpowiedz

4

Jest to błąd w RJSONIO jak można wyraźnie zobaczyć:

> RJSONIO::fromJSON('{"x":"foo\\u2013bar"}') 
      x 
"foo\023bar" 

To działa dobrze w rjson:

> rjson::fromJSON('{"x":"foo\\u2013bar"}') 
$x 
[1] "foo–bar" 

i aby udowodnić, że jest to poprawna wartość:

> Sys.setlocale("LC_ALL", "C") 
[1] "C/C/C/C/C/en_US.UTF-8" 
> rjson::fromJSON('{"x":"foo\\u2013bar"}') 
$x 
[1] "foo<U+2013>bar" 

W swojej analizie dezorientował cię wydrukowany ciąg znaków w stosunku do rzeczywistych ciągów znaków. print cytuje jego zawartość do drukowania - jeśli chcesz zobaczyć rzeczywisty ciąg, możesz użyć cat lub charToRaw. Również scan nie interpretuje żadnych eskapad, więc dostajesz to, co dajesz.

+0

Działa dla mnie, dzięki. –

9

To nie jest błąd w RJSONIO. Zaprojektowano go tak, aby oczekiwał ciągu, który został odczytany przez R i który ma już przetworzone znaki spoza ASCII. Kiedy przekazujemy mu ciąg znaków z \ u, który nie został przetworzony, ale uciekł. Na moim komputerze z locale ustawione na en_US.UTF-8, komenda

fromJSON('{"query":{"categorymembers":[{"ns":0,"title":"Banach\u2013Tarski paradox"}]}}') 

produkuje

$query 
$query$categorymembers 
$query$categorymembers[[1]] 
$query$categorymembers[[1]]$ns 
[1] 0 

$query$categorymembers[[1]]$title 
[1] "Banach–Tarski paradox" 

Zauważ, że znak jest poprzedzony \u nie \\u. Zobacz, jak pojawia się w R po prostu wprowadź ten ciąg.

Tak więc problem pochodzi z metody fromJSON(), dlaczego łańcuch zawiera \ u.
Mogę dodać obsługę w RJSONIO do obsługi takich nieprzetworzonych ciągów.

+0

Dzięki za odpowiedź, Duncan. Widzę, że jeśli użyję twojego łańcucha, to rzeczywiście wyprodukuje dokładnie to, co chcę. Nie wiem, jak to zrobić, aby treść była odczytywana za pośrednictwem RCurl lub readLines. To głównie akademickie, ponieważ przeniosłem się do rjson i działa dobrze. –

+0

Chciałbym usłyszeć więcej o tym, jak radzić sobie z problemem w 'RJSONIO'. Mam niektóre ciągi z przedrostkiem '\\ u', ale nie wiem, jak je przetworzyć przed przekazaniem do' fromJSON'. – daroczig

1

Myślę, że podstawowy problem polega na tym, że opcja libjsonJSON_UNICODE nie jest włączona w RJSONIO. Jednak wydaje się, jakby problem nie objawiać, gdy wejście jest UTF-8 zakodowane:

library(RJSONIO) 
x = "北京填鴨们" 
identical(x, fromJSON(toJSON(x))) 
# [1] TRUE 

Problem pojawia się tylko wtedy, gdy wejście używa JSON uciekł znaków. W tych przypadkach RJSONIO wydaje się generować latin1 wyjście, ale nie znak ustawić kodowanie poprawnie:

x <- fromJSON('["Z\\u00FCrich"]') 
print(x) 
# [1] "Z\xfcrich" 

nchar(x) 
#Error in nchar(x) : invalid multibyte string 1 

Na tym prostym przykładzie możemy to naprawić poprzez ręczne ustawienie kodowania do latin1:

#Set the correct encoding 
Encoding(x) <- "latin1" 
print(x) 
#[1] "Zürich" 

jednak to oczywiście nie będzie działać dla znaków spoza latin1 zestawie

#This should be: "填" 
fromJSON('["\\u586B"]') 
Powiązane problemy