Lesen Sie nur ausgewählte Spalten


134

Kann mir bitte jemand sagen, wie man nur die ersten 6 Monate (7 Spalten) für jedes Jahr der folgenden Daten liest, zum Beispiel unter Verwendung von read.table()?

Year   Jan  Feb  Mar  Apr  May  Jun  Jul  Aug  Sep  Oct  Nov  Dec   
2009   -41  -27  -25  -31  -31  -39  -25  -15  -30  -27  -21  -25
2010   -41  -27  -25  -31  -31  -39  -25  -15  -30  -27  -21  -25 
2011   -21  -27   -2   -6  -10  -32  -13  -12  -27  -30  -38  -29

5
Es ist ein Duplikat von Möglichkeiten, nur ausgewählte Spalten aus einer Datei in R? Zu lesen. , Erwähnt Dirk in seiner Antwort etwa NULLals Spaltenklasse .
Marek


2
@CiroSantilli but 露 宪 六四 六四 but sicher, aber ... Ich habe zuerst gefragt?
StarCub

Ich implizierte keine bessere / schlechtere Beziehung. Darüber hinaus gibt es keine standortübergreifenden Duplikate, die das inkonsistente Stack-Exchange-Netzwerk zulässt, es sei denn, Sie kreuzen sich selbst :-)
Ciro Santilli 15 冠状 病 六四 事件 15

Antworten:


157

Angenommen, die Daten befinden sich in einer Datei data.txt, können Sie das colClassesArgument von verwenden read.table(), um Spalten zu überspringen. Hier sind die Daten in den ersten 7 Spalten "integer"und wir setzen die verbleibenden 6 Spalten so, "NULL"dass sie anzeigen, dass sie übersprungen werden sollen

> read.table("data.txt", colClasses = c(rep("integer", 7), rep("NULL", 6)), 
+            header = TRUE)
  Year Jan Feb Mar Apr May Jun
1 2009 -41 -27 -25 -31 -31 -39
2 2010 -41 -27 -25 -31 -31 -39
3 2011 -21 -27  -2  -6 -10 -32

Wechseln Sie "integer"zu einem der akzeptierten Typen, wie in ?read.tableAbhängigkeit vom tatsächlichen Datentyp beschrieben.

data.txt sieht aus wie das:

$ cat data.txt 
"Year" "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"
2009 -41 -27 -25 -31 -31 -39 -25 -15 -30 -27 -21 -25
2010 -41 -27 -25 -31 -31 -39 -25 -15 -30 -27 -21 -25
2011 -21 -27 -2 -6 -10 -32 -13 -12 -27 -30 -38 -29

und wurde erstellt mit

write.table(dat, file = "data.txt", row.names = FALSE)

wo datist

dat <- structure(list(Year = 2009:2011, Jan = c(-41L, -41L, -21L), Feb = c(-27L, 
-27L, -27L), Mar = c(-25L, -25L, -2L), Apr = c(-31L, -31L, -6L
), May = c(-31L, -31L, -10L), Jun = c(-39L, -39L, -32L), Jul = c(-25L, 
-25L, -13L), Aug = c(-15L, -15L, -12L), Sep = c(-30L, -30L, -27L
), Oct = c(-27L, -27L, -30L), Nov = c(-21L, -21L, -38L), Dec = c(-25L, 
-25L, -29L)), .Names = c("Year", "Jan", "Feb", "Mar", "Apr", 
"May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"), class = "data.frame",
row.names = c(NA, -3L))

Wenn die Anzahl der Spalten vorher nicht bekannt ist, count.fieldsliest die Utility-Funktion die Datei durch und zählt die Anzahl der Felder in jeder Zeile.

## returns a vector equal to the number of lines in the file
count.fields("data.txt", sep = "\t")
## returns the maximum to set colClasses
max(count.fields("data.txt", sep = "\t"))

1
@Benjamin Liest die ersten paar Zeilen aus der Datei mit Argument nrows. Berechnen Sie dann, wie viele Spalten verwendet werden ncol(), oder wie auch immer Sie die Anzahl der zu lesenden / zu ignorierenden Spalten ermitteln möchten. Lesen Sie dann die vollständige Datei anhand dieser Informationen.
Gavin Simpson

1
?? Wenn Sie die Anzahl der Spalten nicht kennen, wie können Sie sie sonst bestimmen, ohne ein wenig davon zu lesen, um daraus zu schließen, wie viele es gibt?
Gavin Simpson

1
@BlueMagister Vielen Dank für die Bearbeitung und die Erwähnung dessen, count.fields()was den in den Kommentaren vorgeschlagenen Prozess automatisiert.
Gavin Simpson

1
@ LéoLéopoldHertz 준영 Nein, und ich bin nicht sicher , wie so etwas für Zeile funktionieren würde Klassen als in einem Datenrahmen, während jede Spalte von einem anderen Typ sein kann, jede Zeile ist per definitionem und als Ergebnis, ungezwungen. Sie müssen beim Import leere Zeilen usw. herausfiltern.
Gavin Simpson

1
@rmf Sie können count.fields()eine Textverbindung übergeben. Lesen Sie also eine Teilmenge der Zeilen mit txt <- readLines(....), stellen Sie eine Verbindung zu den eingelesenen Zeilen her con <- textConnection(txt)und tun Sie dies count.fields(txt). Stellen Sie sicher, dass Sie skipin verwenden count.fields(), um die Kopfzeile zu überspringen, falls es eine gibt. Sie können keine Zeilen in der Datei mit überspringen readLines().
Gavin Simpson

81

Um einen bestimmten Satz von Spalten aus einem Datensatz zu lesen, gibt es mehrere andere Optionen:

1) Mit freadaus dem data.tablePaket:

Sie können die gewünschten Spalten mit dem selectParameter freadaus dem data.tablePaket angeben . Sie können die Spalten mit einem Vektor aus Spaltennamen oder Spaltennummern angeben.

Für den Beispieldatensatz:

library(data.table)
dat <- fread("data.txt", select = c("Year","Jan","Feb","Mar","Apr","May","Jun"))
dat <- fread("data.txt", select = c(1:7))

Alternativ können Sie den dropParameter verwenden, um anzugeben, welche Spalten nicht gelesen werden sollen:

dat <- fread("data.txt", drop = c("Jul","Aug","Sep","Oct","Nov","Dec"))
dat <- fread("data.txt", drop = c(8:13))

Alle ergeben:

> data
  Year Jan Feb Mar Apr May Jun
1 2009 -41 -27 -25 -31 -31 -39
2 2010 -41 -27 -25 -31 -31 -39
3 2011 -21 -27  -2  -6 -10 -32

UPDATE: Wenn Sie keine data.tablefread zurückgeben möchten , verwenden Sie den data.table = FALSE-parameter, z.fread("data.txt", select = c(1:7), data.table = FALSE)

2) Mit read.csv.sqlaus dem sqldfPaket:

Eine weitere Alternative ist die read.csv.sqlFunktion aus dem sqldfPaket:

library(sqldf)
dat <- read.csv.sql("data.txt",
                    sql = "select Year,Jan,Feb,Mar,Apr,May,Jun from file",
                    sep = "\t")

3) Mit den Funktionen read_*aus dem readrPaket:

library(readr)
dat <- read_table("data.txt",
                  col_types = cols_only(Year = 'i', Jan = 'i', Feb = 'i', Mar = 'i',
                                        Apr = 'i', May = 'i', Jun = 'i'))
dat <- read_table("data.txt",
                  col_types = list(Jul = col_skip(), Aug = col_skip(), Sep = col_skip(),
                                   Oct = col_skip(), Nov = col_skip(), Dec = col_skip()))
dat <- read_table("data.txt", col_types = 'iiiiiii______')

Aus der Dokumentation eine Erklärung für die verwendeten Zeichen mit col_types:

Jedes Zeichen repräsentiert eine Spalte: c = Zeichen, i = Ganzzahl, n = Zahl, d = doppelt, l = logisch, D = Datum, T = Datum Uhrzeit, t = Uhrzeit ,? = rate oder _ / - um die Spalte zu überspringen


freadunterstützt jedoch keine komprimierten Dateien. Große Dateien werden normalerweise komprimiert.
CoderGuy123

Es gibt eine Funktionsanforderung, um dies zu aktivieren fread. Bemerkenswert ist, dass freaddie unkomprimierte Datei höchstwahrscheinlich erheblich schneller read.tablegelesen wird als die komprimierte Datei. Ein Beispiel finden Sie hier .
Jaap

Einige unkomprimierte Dateien sind zu groß. ZB arbeite ich mit 1000 Genomdateien. Sie können 60 GB unkomprimiert sein.
CoderGuy123

1
Wie Sie wahrscheinlich wissen, liest R die Daten im Speicher. Ob Sie die komprimierte oder die entpackte Datei lesen, hat keinen Einfluss auf die Größe der resultierenden Daten im Speicher. Wenn Sie 60 GB in Dateien haben, read.tablewerden Sie nicht gespeichert . In diesem Fall sollten Sie sich das ffPaket ansehen .
Jaap

2
@Deleet Sie können freadgroße komprimierte Dateien wie folgt lesen : fread("gunzip -c data.txt.gz", drop = c(8:13)).
Arekolek

8

Sie können auch JDBC verwenden, um dies zu erreichen. Lassen Sie uns eine Beispiel-CSV-Datei erstellen.

write.table(x=mtcars, file="mtcars.csv", sep=",", row.names=F, col.names=T) # create example csv file

Laden Sie den CSV-JDBC-Treiber über diesen Link herunter und speichern Sie ihn: http://sourceforge.net/projects/csvjdbc/files/latest/download

> library(RJDBC)

> path.to.jdbc.driver <- "jdbc//csvjdbc-1.0-18.jar"
> drv <- JDBC("org.relique.jdbc.csv.CsvDriver", path.to.jdbc.driver)
> conn <- dbConnect(drv, sprintf("jdbc:relique:csv:%s", getwd()))

> head(dbGetQuery(conn, "select * from mtcars"), 3)
   mpg cyl disp  hp drat    wt  qsec vs am gear carb
1   21   6  160 110  3.9  2.62 16.46  0  1    4    4
2   21   6  160 110  3.9 2.875 17.02  0  1    4    4
3 22.8   4  108  93 3.85  2.32 18.61  1  1    4    1

> head(dbGetQuery(conn, "select mpg, gear from mtcars"), 3)
   MPG GEAR
1   21    4
2   21    4
3 22.8    4

0

Du machst es so:

df = read.table("file.txt", nrows=1, header=TRUE, sep="\t", stringsAsFactors=FALSE)
colClasses = as.list(apply(df, 2, class))
needCols = c("Year", "Jan", "Feb", "Mar", "Apr", "May", "Jun")
colClasses[!names(colClasses) %in% needCols] = list(NULL)
df = read.table("file.txt", header=TRUE, colClasses=colClasses, sep="\t", stringsAsFactors=FALSE)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.