2013-03-05 12 views
17

mam dużą wektor ciągów postaci:jako numeryczne z przecinkami dziesiętnymi?

Input = c("1,223", "12,232", "23,0") 

itd To znaczy, dziesiętne oddzielone przecinkami, zamiast okresach. Chcę przekonwertować ten wektor na wektor liczbowy. Niestety, as.numeric(Input) po prostu wyświetla NA.

Moim pierwszym instynktem byłoby przejście do strsplit, ale wydaje mi się, że prawdopodobnie będzie to bardzo powolne. Czy ktoś ma jakiś pomysł na szybszą opcję?

Istnieje istniejące pytanie sugerujące, że read.csv2, ale dane ciągi nie są bezpośrednio czytane w ten sposób.

+0

Dlaczego po prostu nie zastąpić przecinków cyframi dziesiętnymi (przez 'gsub', jeśli pamięć przywoła), a następnie zastosować' as.numeric'? –

+2

Nie duplikat. Tysiące separatorów i separatorów dziesiętnych są bardzo różne. As.numeric służy również do konwersji danych, a nie do odczytu danych. – Fhnuzoag

Odpowiedz

33
as.numeric(sub(",", ".", Input, fixed = TRUE)) 

powinien działać.

+0

Działa to dobrze, ale generuje komunikat ostrzegawczy: NA wprowadzone przez wymuszenie '. Jak tego uniknąć? –

+0

ostrzeżenie lub "NA"? – adibender

2

Ponadto, jeśli czytasz w nieprzetworzonych danych, read.table i wszystkie powiązane funkcje mają argument dec. np:

read.table("file.txt", dec=",") 

Kiedy wszystko inne zawiedzie, gsub i sub są twoi przyjaciele.

+1

Nie spodziewałbym się, że pierwszy zadziała, a nie ma to miejsca w przypadku testowego przypadku: 'as.numeric (format (Input, decimal.mark =", "))' [1] NA NA NA –

+0

@DWin - dziwne, że istnieją funkcje dodawania znaczników separujących, np .: 'prettyNum (c (1223,12232,23), big.mark =", ", preserve.width =" none ")' ale nic, aby wrócić do inny sposób? – thelatemail

+0

Z wyjątkiem podejścia adibendera lub zdefiniowania metody "As". Natomiast "decimal.mark" _nie byłoby inne niż 'big.mark'. –

10
scan(text=Input, dec=",") 
## [1] 1.223 12.232 23.000 

Ale to zależy od długości wektora. Użyłem rep(Input, 1e6), aby zrobić długi wektor, a moja maszyna po prostu się zawiesiła. 1e4 jest jednak w porządku. Rozwiązanie @ adibender jest znacznie szybsze. Jeśli będziemy działać na 1E4, A dużo szybciej:

Unit: milliseconds 
     expr  min   lq  median   uq  max neval 
    adibender() 6.777888 6.998243 7.119136 7.198374 8.149826 100 
sebastianc() 504.987879 507.464611 508.757161 510.732661 517.422254 100 
2

Opierając się na rozwiązanie @adibender:

as.numeric(gsub("^([0-9]+),([0-9]+)$","\\1.\\2", input)) 

myślę, że jest bezpieczniejsza mecz ...

0

Jak stwierdził, Łatwiej to zrobić podczas importowania pliku. Thw niedawno wydany pakiet reads ma bardzo przydatne funkcje, locale, dobrze wyjaśniony here, który pozwala użytkownikowi importować liczby ze przecinkiem dziesiętnym ze znakiem locale = locale(decimal_mark = ",") jako argumentem.

Powiązane problemy