Dokumentuję tutaj listę alternatyw dla odczytu plików o stałej szerokości w R, a także podam kilka testów porównawczych, dla których jest najszybszy.
Moje preferowane podejście to połączenie freadz stringi; jest konkurencyjny jako najszybsze podejście i ma dodatkową zaletę (IMO) przechowywania danych jako 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]
Zwróć uwagę, że freadautomatycznie usuwa początkowe i końcowe spacje - czasami jest to niepożądane, w takim przypadku ustawione strip.white = FALSE.
Mogliśmy również zacząć od wektora szerokości kolumn ww, wykonując:
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)
Mogliśmy wybrać, które kolumny wykluczyć bardziej solidnie, używając ujemnych indeksów, takich jak:
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))
Następnie wymień col_ends$beg[ii]ze abs(col_ends$beg[ii])w następnym wierszu:
paste0("V", which(col_ends$beg < 0))
Na koniec, jeśli chcesz, aby nazwy kolumn były również odczytywane programowo, możesz wyczyścić za pomocą 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 != ""]
(zwróć uwagę, że połączenie tego kroku z freadwymagałoby utworzenia kopii tabeli w celu usunięcia wiersza nagłówka, a zatem byłoby nieefektywne w przypadku dużych zestawów danych)
read.fwfaby przeczytać sformatowane dane o stałej szerokości.