2014-06-26 8 views
5

Porównaj konwersję ciągu znaków z as.numeric z tym, jak można wykonać z read.fwf.Możliwa niespójność konwersji z tekstu na numeryczną

as.numeric("457") # 457 
as.numeric("4 57") # NA with warning message 

Teraz odczytać z pliku "fwf.txt" zawierającego dokładnie "5 7 12 4".

foo<-read.fwf('fwf.txt',widths=c(5,5),colClasses='numeric',header=FALSE) 
    V1 V2 
1 57 124 

foo<-read.fwf('fwf.txt',widths=c(5,5),colClasses='character',header=FALSE) 
    V1 V2 
1 5 7 12 4 

Teraz będę pamiętać, że w „numerycznej” wersji, read.fwf robi konkatenacji w ten sam sposób Fortran robi. Byłem tylko trochę zaskoczony, że nie rzuca błędu lub NA w taki sam sposób jak as.numeric. Ktoś wie dlaczego?

+1

'read.fwf' wywołuje' read.table', który jest funkcja, która zajmuje się 'colClasses'. Możesz uzyskać to samo zachowanie, używając 'read.table' zamiast' read.fwf'. Na przykład, jeśli zmienisz zawartość pliku na "5 7 | 12 4", a następnie odczytasz go za pomocą 'read.table (" fwf.txt ", header = FALSE, sep =" | ", colClasses =" numeric ") ', otrzymujesz ten sam wynik. Pomyślałem, że 'read.table' musi pozbyć się odstępów między cyframi, kiedy wie, że klasa ma być numeryczna, ale patrząc na kod funkcji, nie mogłem powiedzieć na pewno, czy to się dzieje. – eipi10

Odpowiedz

5

As @ eipi10 zwrócił uwagę, że zachowanie eliminujące przestrzeń nie jest unikalne dla read.fwf. To faktycznie pochodzi z funkcji scan() (która jest używana przez read.table, która jest używana przez read.fwf). W rzeczywistości funkcja scan() usunie spacje (lub tabulatory, jeśli nie zostały określone jako ogranicznik) z dowolnej wartości, która nie jest znakiem podczas przetwarzania strumienia wejściowego. Po "wyczyszczeniu" wartości spacji, używa tej samej funkcji co as.numeric, aby zmienić tę wartość na liczbę. Przy wartościach znaków nie pobiera żadnej białej spacji, chyba że ustawisz strip.white=TRUE, która usunie tylko spację z początku i końca wartości.

przestrzegać tych przykładów

scan(text="TRU E", what=logical(), sep="x") 
# [1] TRUE 
scan(text="0 . 0 0 7", what=numeric(), sep="x") 
# [1] 0.007 
scan(text=" text ", what=character(), sep="~") 
# [1] " text " 
scan(text=" text book ", what=character(), sep="~", strip.white=T) 
# [1] "text book" 
scan(text="F\tALS\tE", what=logical(), sep=" ") 
# [1] FALSE 

można znaleźć źródło scan() w /src/main/scan.c oraz konkretną część odpowiedzialną za to zachowanie jest around this line.

Jeśli chciał as.numeric zachowywać się jak można utworzyć nową funkcję jak

As.Numeric<-function(x) as.numeric(gsub(" ", "", x, fixed=T)) 

w celu uzyskania

As.Numeric("4 57") 
# [1] 457 
Powiązane problemy