2015-04-07 5 views
13

Gibt es eine Möglichkeit für fread das Verhalten von read.table zu imitieren, wobei die class der Variablen durch die Daten festgelegt wird, eingelesen.Verhindern column-Klasse-Inferenz in fread()

ich mit einem numerischen Daten einige Kommentare unter den Hauptdaten. Wenn ich fread verwende, um die Daten einzulesen, werden die Spalten in Zeichen konvertiert. Durch Setzen der nrow in read.table` kann ich dieses Verhalten jedoch stoppen. Ist das in fread möglich? (Ich würde es vorziehen, die Rohdaten nicht zu ändern oder eine korrigierte Kopie anzufertigen). Dank

Ein Beispiel

d <- data.frame(x=c(1:100, NA, NA, "fff"), y=c(1:100, NA,NA,NA)) 
write.csv(d, "test.csv", row.names=F) 

in_d <- read.csv("test.csv", nrow=100, header=T) 
in_dt <- data.table::fread("test.csv", nrow=100) 

Welche

> str(in_d) 
'data.frame': 100 obs. of 2 variables: 
$ x: int 1 2 3 4 5 6 7 8 9 10 ... 
$ y: int 1 2 3 4 5 6 7 8 9 10 ... 
> str(in_dt) 
Classes ‘data.table’ and 'data.frame': 100 obs. of 2 variables: 
$ x: chr "1" "2" "3" "4" ... 
$ y: int 1 2 3 4 5 6 7 8 9 10 ... 
- attr(*, ".internal.selfref")=<externalptr> 

Als Abhilfe, die ich dachte, erzeugt würde ich in der Lage sein read.table zu verwenden, in einer Zeile zu lesen, die Klasse erhalten und die colClasses gesetzt, aber Ich verstehe das nicht.

cl <- read.csv("test.csv", nrow=1, header=T) 
cols <- unname(sapply(cl, class)) 
in_dt <- data.table::fread("test.csv", nrow=100, colClasses=cols) 
str(in_dt) 

Verwendung Windows8.1 R Version 3.1.2 (2014.10.31) Plattform: x86_64-W64-mingw32/x64 (64-Bit)

+3

Laut einem vernünftigen Plan, aber ich lese eigentlich die Hilfe-Seite: "Fread wird nur eine Spalte auf einen höheren Typ hochstufen, wenn colClasses es anfordert. Es wird keine Spalte auf einen niedrigeren Typ herabstufen, da sich NAs ergeben würden Solche Spalten müssen Sie anschließend selbst erzwingen, wenn Sie wirklich Datenverlust benötigen. " Es scheint, dass selbst das Beschränken des Lesens auf 5 Zeilen fehlschlägt. Ich denke, ich erinnere mich, dass der ColClasses-Mechanismus eine ziemlich neue Ergänzung war, also sollten Sie vielleicht eine Feature-Anfrage einreichen. Matthew und Arun sind oft sehr zuvorkommend. –

+2

Sicher muss es eine DT-Strategie geben, um alle Spalten zu numerisch zu zwingen? Setzen Sie '.SDcols' auf einen geeigneten Vektor und etwas in der Art:' DT [, .SD: = lapply (.SDcols, as.numeric), .SDcols = vec] '. Ich bin kein DT-Benutzer, aber ich bin mir sicher, dass es einen minimalen Tipp-Ansatz gibt und ich vermute, dass Sie ihn in SO-Antworten finden. –

+0

@BondedDust; Ich bin auch kein DT-Benutzer, seine nur lesen.tabelle hat (ernsthafter) Probleme mit meinen Daten als fread ist. Ich werde auf SO schauen. danke – user2957945

Antwort

17

Option 1: Mit a Systembefehl

fread() ermöglicht die Verwendung eines Systembefehls in seinem ersten Argument. Wir können damit die Anführungszeichen in der ersten Spalte der Datei entfernen.

indt <- data.table::fread("cat test.csv | tr -d '\"'", nrows = 100) 
str(indt) 
# Classes ‘data.table’ and 'data.frame': 100 obs. of 2 variables: 
# $ x: int 1 2 3 4 5 6 7 8 9 10 ... 
# $ y: int 1 2 3 4 5 6 7 8 9 10 ... 
# - attr(*, ".internal.selfref")=<externalptr> 

Der Systembefehlcat test.csv | tr -d '\"'erläutert:

  • cat test.csv die Datei auf der Standardausgabe ausliest
  • | ein Rohr, das Ausgangssignal des vorherigen Befehls als Eingabe für die nächste Verwendung Befehl
  • tr -d '\"' löscht (-d) Alle Vorkommen von doppelten Anführungszeichen ('\"') aus dem Stromeingang

Option 2: Coercion nach

Lesen

Da Option 1 scheint nicht auf Ihrem System zu arbeiten, ein anderer Möglichkeit besteht darin, die Datei wie Sie zu lesen, aber konvertieren Sie die x Spalte mit type.convert().

library(data.table) 
indt2 <- fread("test.csv", nrows = 100)[, x := type.convert(x)] 
str(indt2) 
# Classes ‘data.table’ and 'data.frame': 100 obs. of 2 variables: 
# $ x: int 1 2 3 4 5 6 7 8 9 10 ... 
# $ y: int 1 2 3 4 5 6 7 8 9 10 ... 
# - attr(*, ".internal.selfref")=<externalptr> 

Randbemerkung: Ich ziehe es in der Regel type.convert() über as.numeric() zu verwenden, um die „NAs durch Zwang eingeführt“ zu vermeiden Warnung in einigen Fällen ausgelöst.Zum Beispiel

x <- c("1", "4", "NA", "6") 
as.numeric(x) 
# [1] 1 4 NA 6 
# Warning message: 
# NAs introduced by coercion 
type.convert(x) 
# [1] 1 4 NA 6 

Aber natürlich können Sie as.numeric() auch verwenden.


Hinweis: Diese Antwort geht davon aus data.table dev v1.9.5

+0

Dank Richard, dies wirft jedoch einen Fehler auf meinem System. Ich benutze Windows 8.1 – user2957945

+0

Danke für die zusätzlichen Informationen. Ich habe die dev-Version aber denselben Fehler unter Windows installiert (funktioniert, mit hilfreicher Warnung auf Linux). Können Sie bitte den Systemaufruf erklären? – user2957945

+1

@ user2957945 - Okay gut zu wissen. Ich fügte eine zweite Option hinzu, die ausreichend effizient sein sollte –

-2

Ok, der Kunden abusing CSV format absichtlich zu schreiben ist Zeichenfolge Zeilen zu einer Integer-Spalte Hinter, aber ohne diese Zeilen mit einem comment.char Start (#) .

Dann erwarten Sie irgendwie, dass Sie fread() 's Typ-Inferenz überschreiben können, um diese als ganze Zahl zu lesen, indem Sie nrow verwenden, um zu versuchen, es zu begrenzen, um nur die ganzzahligen Reihen zu sehen. read.csv(..., nrow) akzeptiert dies, aber fread() verwendet immer alle Zeilen für Typ-Inferenz (nicht nur die von nrow, skip, header angegebenen), und auch wenn sie mit comment.char beginnen (das ist ein Fehler).

  1. Klingt wie ein Missbrauch von CSV. Ihre Kommentarzeilen sollten mit #
  2. vorangestellt werden. Ja, fread() muss korrigiert/erweitert werden, um Kommentarzeilen für Typinferenz zu ignorieren.
  3. Vorerst Sie mit fread() durch Nachbearbeitung der Daten-Tabelle lesen umgehen können
  4. Es ist fraglich, ob fread() das gewünschte Verhalten geändert werden soll, unterstützen. Mit nrows zu begrenzen, was zu ausgesetzt wird Typ-Inferenz . Es könnte Ihren (ziemlich einzigartigen) Fall beheben und einige andere brechen.

Ich sehe nicht, warum Sie (EDIT: der Kunde) können Ihre Kommentare zu einer separaten .txt/README/Daten-Wörterbuch-Datei nicht schreiben die .csv zu begleiten. Die Praxis, eine separate Datenwörterbuchdatei zu verwenden, ist ziemlich gut etabliert. Ich habe noch nie jemanden gesehen, der dies zu einer CSV-Datei macht. Verschieben Sie die Kommentare zumindest in die Kopfzeile und nicht in eine Fußzeile.

+0

Die CSV hat keine mehrzeiligen Header. Es hat unerwünschte Sachen am Ende der Datei –

+0

Ok, dann nachfolgende (String) Kommentarzeilen, ohne führende '#'. Warum haben Sie sie nicht einfach manuell an die write.csv angehängt? – smci

+0

Es ist nicht meine Frage, aber ich vermute, dass OP bereits die Datei hat und nur 'write.csv()' verwendet, um ein Beispiel zu erstellen. –