2012-05-04 36 views
6

Mam plik, który czytałem w na R i jest tłumaczone na dataframe (tzw CA1), aby mieć strukturę jak następuje:Konwersja znak wartości numerycznej w R

Station_ID Guage_Type Lat Long  Date Time_Zone Time_Frame H0 H1 H2 H3 H4 H5 H6 H7 H8 H9 H10 H11 H12 H13 H14 H15 H16 H17 H18 H19 H20 H21 H22 H23 
1 4457700   HI 41.52 124.03 19480701   8  LST 0 0 0 0 0 0 0 0 0 0 0 0 MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS 
2 4457700   HI 41.52 124.03 19480705   8  LST 0 1 1 1 1 1 2 2 2 4 5 5 4 7 1 1 0 0 10 13 5 1 1 3 
3 4457700   HI 41.52 124.03 19480706   8  LST 1 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
4 4457700   HI 41.52 124.03 19480727   8  LST 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
5 4457700   HI 41.52 124.03 19480801   8  LST 0 0 0 0 0 0 0 0 0 0 0 0 MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS 
6 4457700   HI 41.52 124.03 19480817   8  LST 0 0 0 0 0 0 ACC ACC ACC ACC ACC ACC 6 1 0 0 0 0 0 0 0 0 0 0 

H0 przez H23 są wczytać jako znak(), ponieważ będą przypadki, gdy wartość nie będzie numeryczna i będą miały wartości takie jak MIS, ACC lub DEL.

Moje pytanie: czy istnieje sposób na typograficzne wartości dla każdej kolumny od H0 do H23, aby były numeryczne i mają wartości znakowe (MIS, ACC, DEL) jako NA lub NAN, które mogę przetestować dla niego, jeśli są (is.nan lub is.na), więc mogę uruchomić kilka modeli numerycznych. A może najlepiej byłoby zmienić wartości znaków na identyfikator, na przykład -9999?

Próbowałem na wiele sposobów. Znalazłem kilka na tej stronie, ale nic z pracy. Takich jak:

for (i in 8:31) 
{ 
    CA1[6,i] <- as.numeric(as.character(CA1[6,i])) 
} 

co oczywiście daje ostrzeżenia, ale jak sprawdzić, czy dwa konkretne wartości is_numeric() (CA1 [6,8] i CA1 [6,19]) uzyskać fałszywe oświadczenie dla obu stron. Pierwszy nie rozumiem dlaczego, ale drugi robię, ponieważ jest to "". Mogę jednak przetestować to przy pomocy is.na (CA1 [6,19]) i zwraca true, co jest w porządku, ponieważ wiem, że nie jest to wartość numeryczna.

Drugim sposobem Próbowałem to:

for (i in 8:31) 
{ 
    CA1[6,i] <- as.numeric(levels(CA1[6,i]))[CA1[6,i]] 
} 

którą uzyskać takie same wyniki jak poprzednio.

Czy istnieje sposób robienia tego, co próbuję zrobić w sposób efektywny? Twoja pomoc jest bardzo doceniana. Dziękujemy

Odpowiedz

6

Bezpośrednim problemem jest to, że każda kolumna ramki danych może zawierać tylko wartości jednego typu. W twoim kodzie oznacza to, że tylko jedna wartość jest konwertowana w każdej kolumnie, więc po wstawieniu po konwersji musi zostać przymuszona do ciągu, aby dopasować się do reszty kolumny.

Możesz rozwiązać ten problem, przekształcając całą kolumnę za jednym razem, dzięki czemu kolumna zostanie całkowicie zastąpiona. tj usunąć 6:

for (i in 8:31) 
{ 
    CA1[,i] <- as.numeric(as.character(CA1[,i])) 
} 
+0

dziękuję ci za pomoc, masz rację co do konwersji z powrotem na ciąg, aby dopasować kolumnę. Powodem, dla którego postawiłem 6, było przetestowanie go w jednym rzędzie, aby sprawdzić, czy zadziałało, ale niestety mały test był przyczyną mojego problemu. Niemniej dziękuję za pomoc. –

6

Podczas odczytywania danych można zazwyczaj określić typ kolumn. Na przykład read.table/read.csv ma argument colClasses.

# Something like this 
read.table('foo.txt', header=TRUE, colClasses=c('integer', 'factor', 'numeric', numeric', 'Date')) 

Aby uzyskać więcej informacji, zobacz ?read.table.

2

Po odpowiedzi na Tommy'ego, potencjalnie mogłyby poradzić sobie z tym problemem przy wczytywaniu danych. Jeśli "MIS", "ACC" i "DEL" zawsze oznaczają brakujące wartości, można użyć argumentu na.strings w read.table.

read.table('foo.txt', header=TRUE, na.strings = c("MIS", "ACC", "DEL")) 

Jeśli istnieją inne ciągi znaków, które zawsze oznaczają brakujące wartości, można dodać je do powyższego wektora.

Jeśli na przykład "MIS" pojawi się w kolumnie Time_Frame i ma znaczenie inne niż oznaczenie brakującej wartości, NIE PODEJMUJ TEGO PODEJŚCIA!

+0

Dziękuję za pomoc, jednak czytam dane jako ramkę danych w trzech liniach, ponieważ jest niezorganizowana. Fragment kodu, który widziałem z mojego postu, to sposób, w jaki to wyczyściłem. Jednak próbowałem go używać na.strings = c ("MIS", "ACC", "DEL")), jak wspomniałeś, chociaż mam ten sam problem, gdy jest on zapisany w danych, ponieważ większość danych w kolumnie jest znak typu (jak wyjaśniono przez dpaupp). Ale twoja metoda jest świetna i na pewno będę o niej pamiętać na przyszłość. Dziękuję za pomoc –