быстрый способ, чтобы прочитать фиксированной ширины файлы


read.fwflong

Я работаю с большим количеством фиксированной ширины файлы (т. е. без разделительных знаков), что мне нужно прочитать в р. Так, там, как правило, определение ширины столбца для разбора строки в переменные. Я могу использовать, чтобы прочитать данные без проблем. Однако, для больших файлов, это может занять некоторое время. За последних данных, это заняло 800 секунд прочитать в наборе данных с ~500 000 строк и 143 переменных.

seer9 <- read.fwf("~/data/rawdata.txt",   widths = cols,  header = FALSE,  buffersize = 250000,  colClasses = "character",  stringsAsFactors = FALSE))
freaddata.table

в пакет в R является удивительным для решения самых читаемых данных проблем, за исключением не разобрать фиксированной ширины файлы. Однако, я могу читать каждую строку в качестве отдельного строку символов (~500 000 строк, 1 столбец). Это занимает 3-5 секунд. (Я люблю данные.стол.)

seer9 <- fread("~/data/rawdata.txt", colClasses = "character",               sep = "\n", header = FALSE, verbose = TRUE)
heresubstrherestrsplitsedimplement.freadsubstr()

Есть ряд хороших должностей, так как для разбора текстовых файлов. Предложение увидеть JHoward , чтобы создать матрицу начале и конце колонны, а также для анализа данных. Предложение увидеть GSEE в использовании . Я не мог выяснить, как заставить это работать с этими данными. (Кроме того, Майкл Смит сделал некоторые предложения на данные.список рассылки участием, которые были не в состоянии ) сейчас, через и я могу сделать все это примерно 25-30 секунд. Обратите внимание, что принуждение к данным.таблица в конце берет кусок времени (5 сек?).

end_col <- cumsum(cols)start_col <- end_col - cols + 1start_end <- cbind(start_col, end_col) # matrix of start and end positionstext <- lapply(seer9, function(x) {        apply(start_end, 1, function(y) substr(x, y[1], y[2]))         })dt <- data.table(text$V1)setnames(dt, old = 1:ncol(dt), new = seervars)
parallelmclapplydata.tablelapply

Что мне интересно, является ли это может быть улучшена дальше? Я знаю, что я не единственный, кто должен исправлено чтение файлов ширины, так что если это может быть сделано быстрее, это сделает загрузку даже больших файлов (миллионы строк) более терпимым. Я попытался с помощью С и вместо того , но те ничего не изменить. (Вероятно, из-за моей неопытности в р.) Я представляю, что функция Rcpp может быть написана, чтобы сделать это действительно быстро, но это за пределами моих возможностей. Кроме того, я не можете использовать lapply и соответствующим образом применить.

magrittr

Мои данные.реализация таблицы (с цепочкой) занимает столько же времени:

text <- seer9[ , apply(start_end, 1, function(y) substr(V1, y[1], y[2]))] %>%   data.table(.)

Может кто-нибудь сделать предложения для повышения скорости этого? Или это примерно так же хорошо, как он получает?

NOT

Вот код для создания аналогичных данных.таблицы в р (а не ссылок на фактические данные). Он должен иметь 331 символов, и 500 000 строк. Есть места, чтобы имитировать недостающие поля в данных, но это пробел в данных. (Я читаю данные провидец, в случае, если кому-то интересно.) Также в том числе ширины столбца (столбцов) и переменных (seervars) в случае, если это помогает кто-то другой. Это реальные колонки и определения переменных для сведения провидец.

seer9 <-  data.table(rep((paste0(paste0(letters, 1000:1054, " ", collapse = ""), " ")),                 500000))cols = c(8,10,1,2,1,1,1,3,4,3,2,2,4,4,1,4,1,4,1,1,1,1,3,2,2,1,2,2,13,2,4,1,1,1,1,3,3,3,2,3,3,3,3,3,3,3,2,2,2,2,1,1,1,1,1,6,6,6,2,1,1,2,1,1,1,1,1,2,2,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,7,5,4,10,3,3,2,2,2,3,1,1,1,1,2,2,1,1,2,1,9,5,5,1,1,1,2,2,1,1,1,1,1,1,1,1,2,3,3,3,3,3,3,1,4,1,4,1,1,3,3,3,3,2,2,2,2)seervars <- c("CASENUM", "REG", "MAR_STAT", "RACE", "ORIGIN", "NHIA", "SEX", "AGE_DX", "YR_BRTH", "PLC_BRTH", "SEQ_NUM", "DATE_mo", "DATE_yr", "SITEO2V", "LATERAL", "HISTO2V", "BEHO2V", "HISTO3V", "BEHO3V", "GRADE", "DX_CONF", "REPT_SRC", "EOD10_SZ", "EOD10_EX", "EOD10_PE", "EOD10_ND", "EOD10_PN", "EOD10_NE", "EOD13", "EOD2", "EOD4", "EODCODE", "TUMOR_1V", "TUMOR_2V", "TUMOR_3V", "CS_SIZE", "CS_EXT", "CS_NODE", "CS_METS", "CS_SSF1", "CS_SSF2", "CS_SSF3", "CS_SSF4", "CS_SSF5", "CS_SSF6", "CS_SSF25", "D_AJCC_T", "D_AJCC_N", "D_AJCC_M", "D_AJCC_S", "D_SSG77", "D_SSG00", "D_AJCC_F", "D_SSG77F", "D_SSG00F", "CSV_ORG", "CSV_DER", "CSV_CUR", "SURGPRIM", "SCOPE", "SURGOTH", "SURGNODE", "RECONST", "NO_SURG", "RADIATN", "RAD_BRN", "RAD_SURG", "SS_SURG", "SRPRIM02", "SCOPE02", "SRGOTH02", "REC_NO", "O_SITAGE", "O_SEQCON", "O_SEQLAT", "O_SURCON", "O_SITTYP", "H_BENIGN", "O_RPTSRC", "O_DFSITE", "O_LEUKDX", "O_SITBEH", "O_EODDT", "O_SITEOD", "O_SITMOR", "TYPEFUP", "AGE_REC", "SITERWHO", "ICDOTO9V", "ICDOT10V", "ICCC3WHO", "ICCC3XWHO", "BEHANAL", "HISTREC", "BRAINREC", "CS0204SCHEMA", "RAC_RECA", "RAC_RECY", "NHIAREC", "HST_STGA", "AJCC_STG", "AJ_3SEER", "SSG77", "SSG2000", "NUMPRIMS", "FIRSTPRM", "STCOUNTY", "ICD_5DIG", "CODKM", "STAT_REC", "IHS", "HIST_SSG_2000", "AYA_RECODE", "LYMPHOMA_RECODE", "DTH_CLASS", "O_DTH_CLASS", "EXTEVAL", "NODEEVAL", "METSEVAL", "INTPRIM", "ERSTATUS", "PRSTATUS", "CSSCHEMA", "CS_SSF8", "CS_SSF10", "CS_SSF11", "CS_SSF13", "CS_SSF15", "CS_SSF16", "VASINV", "SRV_TIME_MON", "SRV_TIME_MON_FLAG", "SRV_TIME_MON_PA", "SRV_TIME_MON_FLAG_PA", "INSREC_PUB", "DAJCC7T", "DAJCC7N", "DAJCC7M", "DAJCC7STG", "ADJTM_6VALUE", "ADJNM_6VALUE", "ADJM_6VALUE", "ADJAJCCSTG")
UPDATE:

Лаф сделал всю прочитал всего за 7 секунд из сырого .файл txt. Может быть, есть еще более простой способ, но я сомневаюсь, что мог бы сделать гораздо лучше. Удивительный пакет.

27 July 2015 Update

Просто хотел дать небольшой апдейт к этому. Я использовал новый пакет readr, и я смог прочитать весь файл за 5 секунд, используя readr::read_fwf.

seer9_readr <- read_fwf("path_to_data/COLRECT.TXT",  col_positions = fwf_widths(cols))

Кроме того, обновленный стринги::функция stri_sub как минимум вдвое быстрее, чем базы::функцию substr(). Так, в приведенном выше код использует fread операционной, чтобы прочитать файл (около 4 секунд), затем применить для разбора каждой строки, добыча 143 переменных ушло около 8 секунд с стринги::stri_sub по сравнению с 19 для основания::подстрока. Так, fread операционной плюс stri_sub еще только около 12 секунд для запуска. Не плохо.

seer9 <-  fread("path_to_data/COLRECT.TXT",       colClasses = "character",   sep = "\n",   header = FALSE)text <- seer9[ , apply(start_end, 1, function(y) substr(V1, y[1], y[2]))] %>%   data.table(.)

10 обновление 2015 декабря:

answer below

Пожалуйста, Также смотрите на @MichaelChirico, кто добавил некоторые большие ориентиры и пакет iotools.