Określanie colClasses w pliku read.csv

108

Próbuję określić colClassesopcje w read.csvfunkcji w R. W moich danych pierwsza kolumna „czas” jest w zasadzie wektorem znakowym, podczas gdy pozostałe kolumny są liczbami.

data <- read.csv("test.csv", comment.char="" , 
                 colClasses=c(time="character", "numeric"), 
                 strip.white=FALSE)

W powyższym poleceniu chciałbym, aby R czytał w kolumnie „czas” jako „znak”, a resztę jako liczbę. Chociaż zmienna „data” miała poprawny wynik po zakończeniu polecenia, R zwrócił następujące ostrzeżenia. Zastanawiam się, jak mógłbym naprawić te ostrzeżenia?

Warning messages:
 1: In read.table(file = file, header = header, sep = sep, quote = quote,  :
    not all columns named in 'colClasses' exist
 2: In tmp[i[i > 0L]] <- colClasses :
    number of items to replace is not a multiple of replacement length

Derek

defoo
źródło

Odpowiedzi:

78

Wektor colClasses musi mieć długość równą liczbie zaimportowanych kolumn. Przypuśćmy, że pozostałe kolumny w Twoim zestawie danych to 5:

colClasses=c("character",rep("numeric",5))
George Dontas
źródło
7
prawdopodobnie można użyć poniższego, aby przeczytać pierwszą linię csv i określić, ile jest kolumn. scan (csv, sep = ',', what = "character", nlines = 1)
defoo
34
To właściwie jest niepoprawna odpowiedź i na chwilę mnie wyrzuciło. Prawidłowa odpowiedź znajduje się poniżej. Nie próbowałem być palantem, chciałem tylko upewnić się, że to nie przydarzy się nikomu innemu.
Rob
3
@Rob W moim przypadku jest to nadal poprawna odpowiedź, kiedy trzeba również określić klasy innych zmiennych, a nie są one automatycznie rozpoznawane jako takie przez read.table.
tchakravarty
173

Możesz określić colClasse tylko dla jednej kolumny.

W swoim przykładzie powinieneś użyć:

data <- read.csv('test.csv', colClasses=c("time"="character"))
Etienne
źródło
21
Nie żeby to miało duże znaczenie, ale okazało się, że działa to bez cytowania nazwy kolumny.
Hendy,
To podejście jest w rzeczywistości bardzo przydatne, gdy próbuje się odczytać liczby całkowite w cudzysłowach jako znak. Dzięki!
nils-holmberg
14

Zakładając, że kolumna „czas” zawiera co najmniej jedną obserwację ze znakiem nienumerycznym, a wszystkie pozostałe kolumny zawierają tylko liczby, wówczas domyślną wartością parametru „read.csv” będzie odczytanie „czasu” jako „czynnika” i całej reszty kolumny jako „numeryczne”. Dlatego ustawienie „stringsAsFactors = F” będzie miało taki sam skutek, jak ręczne ustawienie „colClasses”, tj.

data <- read.csv('test.csv', stringsAsFactors=F)
wkmor1
źródło
10

Jeśli chcesz odwoływać się do nazw z nagłówka zamiast numerów kolumn, możesz użyć czegoś takiego:

fname <- "test.csv"
headset <- read.csv(fname, header = TRUE, nrows = 10)
classes <- sapply(headset, class)
classes[names(classes) %in% c("time")] <- "character"
dataset <- read.csv(fname, header = TRUE, colClasses = classes)
scentoni
źródło
4

W przypadku wielu kolumn z datą i godziną bez nagłówka i wielu kolumn powiedzmy, że moje pola daty i godziny znajdują się w kolumnach 36 i 38 i chcę, aby były odczytywane jako pola znakowe:

data<-read.csv("test.csv", head=FALSE,   colClasses=c("V36"="character","V38"="character"))                        
Odyseusz Itaka
źródło
3

Wiem, że OP zapytał o utils::read.csvfunkcję, ale pozwól mi odpowiedzieć na te, które przychodzą tutaj, szukając, jak to zrobić, używając readr::read_csvz tidyverse.

read_csv ("test.csv", col_names=FALSE, col_types = cols (.default = "c", time = "i"))

Powinno to ustawić domyślny typ dla wszystkich kolumn jako znak , podczas gdy czas będzie analizowany jako liczba całkowita.

elcortegano
źródło
0

Jeśli połączymy to, co wnieśli @Hendy i @Oddysseus Ithaca, otrzymamy czystszy i bardziej ogólny (tj. Dający się dostosować?) Fragment kodu.

    data <- read.csv("test.csv", head = F, colClasses = c(V36 = "character", V38 = "character"))                        
seapen
źródło