Как «загрузить» список файлов с разным количеством столбцов?

#r #function #data.table #fread

Вопрос:

Обычно меня заставляют читать списки файлов, которые все имеют один и тот же формат, одинаковое количество столбцов. Моя функция выглядит так :

 fun.read <- function(files) {
  read <- function(filename){
    DT <- data.table::fread(filename, header = FALSE, sep = ";", select = 1:7, col.names = c(...))
  }
  lst <- lapply(files, read)
}
 

Это прекрасно работает.

Но теперь я должен сделать то же самое, предполагая, что в моих файлах не одинаковое количество столбцов. То, как я это делаю, например, что-то вроде :

 fun.read <- function(files) {
  read <- function(filename){
    if (max(count.fields(filename, sep = ";")) == 7) {
      DT <- data.table::fread(filename, header = FALSE, sep = ";", select = 1:7, col.names = c(...))
    } else if (max(count.fields(filename, sep = ";")) == 8){
      DT <- data.table::fread(filename, header = FALSE, sep = ";", select = 1:8, col.names = c(...))
    }
  }
  lst <- lapply(files, read)
}
 

Кажется, это тоже работает нормально, но мне интересно, нет ли более эффективного / элегантного способа сделать это ?

Я рассматривал этот fill = TRUE вариант, но безуспешно…

Большое спасибо !!

Комментарии:

1. Почему вы должны указать select = 1:7 . Если вы не укажете, то он прочитает все столбцы. и вам не нужно ничего, если/иначе

2. действительно. lapply(files, fread) кажется, здесь логичный ответ.

3. @akrun, я думаю, из-за названий кол. Иногда это вектор длиной 7, иногда длиной 8.

4. @Discuss23 Вам просто нужен код, указанный Оливером. В sep этом нет необходимости, так как это будет автоматически обнаружено во fread

5. Я, честно говоря, еще не проверял это. Но в файле справки указано, что он использует первые несколько строк для обнаружения разделителя (если я правильно помню). Если ваш набор данных не очень велик, это, скорее всего, лишь малая часть затраченного времени.

Ответ №1:

На случай, если это может быть кому-то полезно, вот как я облегчил свой сценарий : в том числе if в col.names()

 x <- max(count.fields(filename, sep = ";"))
DT <- data.table::fread(filename, header = FALSE, sep = ";", col.names = c("...", "...", "...", if(x>3)"..."))
 

Спасибо.