Ich dokumentiere hier die Liste der Alternativen zum Lesen von Dateien mit fester Breite in R sowie einige Benchmarks, für die die schnellsten sind.
Mein bevorzugter Ansatz ist es, fread
mit zu kombinieren stringi
; Es ist als schnellster Ansatz wettbewerbsfähig und hat den zusätzlichen Vorteil (IMO), dass Ihre Daten wie folgt gespeichert werden data.table
:
library(data.table)
library(stringi)
col_ends <-
list(beg = c(1, 10, 15, 19, 23, 28, 32, 36,
41, 45, 49, 54, 58),
end = c(9, 14, 18, 22, 27, 31, 35,
40, 44, 48, 53, 57, 61))
data = fread(
"http://www.cpc.ncep.noaa.gov/data/indices/wksst8110.for",
header = FALSE, skip = 4L, sep = NULL
)[, lapply(1:(length(col_ends$beg)),
function(ii)
stri_sub(V1, col_ends$beg[ii], col_ends$end[ii]))
][ , paste0("V", c(2, 5, 8, 11)) := NULL]
# V1 V3 V4 V6 V7 V9 V10 V12 V13
# 1: 03JAN1990 23.4 -0.4 25.1 -0.3 26.6 0.0 28.6 0.3
# 2: 10JAN1990 23.4 -0.8 25.2 -0.3 26.6 0.1 28.6 0.3
# 3: 17JAN1990 24.2 -0.3 25.3 -0.3 26.5 -0.1 28.6 0.3
# 4: 24JAN1990 24.4 -0.5 25.5 -0.4 26.5 -0.1 28.4 0.2
# 5: 31JAN1990 25.1 -0.2 25.8 -0.2 26.7 0.1 28.4 0.2
# ---
# 1365: 24FEB2016 27.1 0.9 28.4 1.8 29.0 2.1 29.5 1.4
# 1366: 02MAR2016 27.3 1.0 28.6 1.8 28.9 1.9 29.5 1.4
# 1367: 09MAR2016 27.7 1.2 28.6 1.6 28.9 1.8 29.6 1.5
# 1368: 16MAR2016 27.5 1.0 28.8 1.7 28.9 1.7 29.6 1.4
# 1369: 23MAR2016 27.2 0.9 28.6 1.4 28.8 1.5 29.5 1.2
Beachten Sie, dass fread
führende und nachfolgende Leerzeichen automatisch entfernt werden - manchmal ist dies unerwünscht. In diesem Fall wird dies festgelegt strip.white = FALSE
.
Wir hätten auch mit einem Vektor der Spaltenbreiten beginnen können, ww
indem wir Folgendes getan hätten:
ww <- c(9, 5, 4, 4, 5, 4, 4, 5, 4, 4, 5, 4, 4)
nd <- cumsum(ww)
col_ends <-
list(beg = c(1, nd[-length(nd)]+1L),
end = nd)
Und wir hätten auswählen können, welche Spalten robuster ausgeschlossen werden sollen, indem wir negative Indizes wie:
col_ends <-
list(beg = c(1, -10, 15, 19, -23, 28, 32, -36,
41, 45, -49, 54, 58),
end = c(9, 14, 18, 22, 27, 31, 35,
40, 44, 48, 53, 57, 61))
Dann ersetzen Sie col_ends$beg[ii]
mit abs(col_ends$beg[ii])
und in der nächsten Zeile:
paste0("V", which(col_ends$beg < 0))
Wenn Sie möchten, dass die Spaltennamen auch programmgesteuert gelesen werden, können Sie Folgendes bereinigen readLines
:
cols <-
gsub("\\s", "",
sapply(1:(length(col_ends$beg)),
function(ii)
stri_sub(readLines(URL, n = 4L)[4L],
col_ends$beg[ii]+1L,
col_ends$end[ii]+1L)))
cols <- cols[cols != ""]
(Beachten Sie, dass zum Kombinieren dieses Schritts mit fread
das Erstellen einer Kopie der Tabelle erforderlich ist, um die Kopfzeile zu entfernen, und daher für große Datenmengen ineffizient wäre.)
read.fwf
sich die gelesenen formatierten Daten mit fester Breite an.