Подтвердить что ты не робот

Чтение в нескольких CSV файлах с разным количеством строк для пропуска при запуске файла

Мне нужно прочитать примерно 300 отдельных CSV. Мне удалось автоматизировать процесс, используя петлевые и структурированные имена CSV. Однако каждый CSV имеет 14-17 строк мусора в начале и он изменяется случайным образом, поэтому жесткое кодирование параметра "skip" в команде read.table не будет работать. Имена столбцов и количество столбцов одинаковы для каждого CSV.

Вот пример того, с чем я против:

QUICK STATISTICS:

      Directory: Data,,,,
           File: Final_Comp_Zn_1
      Selection: SEL{Ox*1000+Doma=1201}
         Weight: None,,,
     ,,Variable: AG,,,

Total Number of Samples: 450212  Number of Selected Samples: 277


Statistics

VARIABLE,Min slice Y(m),Max slice Y(m),Count,Minimum,Maximum,Mean,Std.Dev.,Variance,Total Samples in Domain,Active Samples in Domain AG,  
6780.00,   6840.00,         7,    3.0000,   52.5000,   23.4143,   16.8507,  283.9469,        10,        10 AG,   
6840.00,   6900.00,         4,    4.0000,    5.5000,    4.9500,    0.5766,    0.3325,        13,        13 AG,   
6900.00,   6960.00,        16,    1.0000,   37.0000,    8.7625,    9.0047,   81.0848,        29,        29 AG,   
6960.00,   7020.00,        58,    3.0000,   73.5000,   10.6931,   11.9087,  141.8172,       132,       132 AG,   
7020.00,   7080.00,        23,    3.0000,  104.5000,   15.3435,   23.2233,  539.3207,        23,        23 AG,   
7080.00,   7140.00,        33,    1.0000,   15.4000,    3.8152,    2.8441,    8.0892,        35,        35 AG,

В основном я хочу читать из строки VARIABLE,Min slice Y(m),Max slice Y(m),.... Я могу придумать несколько решений, но я не знаю, как я буду программировать. В любом случае я могу:

  • Сначала прочитайте CSV и как-то выясните, сколько строк мусора есть, а затем перечитайте его и укажите правильное количество строк для пропусков? Или
  • Скажите read.table, чтобы начать чтение, когда он находит имена столбцов (так как они одинаковы для каждого CSV) и игнорировать все до этого?

Я думаю, что решение (2) было бы наиболее подходящим, но я открыт для любых предложений!

4b9b3361

Ответ 1

Функция fread из пакета data.table выполняет автоматическое определение количества пропущенных строк. Эта функция находится в стадии разработки.

Вот пример кода:

require(data.table)

cat("blah\nblah\nblah\nVARIABLE,X1,X2\nA,1,2\n", file="myfile1.csv")
cat("blah\nVARIABLE,A1,A2\nA,1,2\n", file="myfile2.csv")
cat("blah\nblah\nVARIABLE,Z1,Z2\nA,1,2\n", file="myfile3.csv")

lapply(list.files(pattern = "myfile.*.csv"), fread)

Ответ 2

Здесь приведен минимальный пример одного подхода, который можно принять.

Сначала создайте некоторые файлы csv, похожие на те, которые вы описываете:

cat("blah\nblah\nblah\nVARIABLE,X1,X2\nA,1,2\n", file="myfile1.csv")
cat("blah\nVARIABLE,A1,A2\nA,1,2\n", file="myfile2.csv")
cat("blah\nblah\nVARIABLE,Z1,Z2\nA,1,2\n", file="myfile3.csv")

Во-вторых, укажите, где начинаются данные:

linesToSkip <- sapply(list.files(pattern = "myfile.*.csv"), 
                      function(x) grep("^VARIABLE", readLines(x))-1)

В-третьих, используйте эту информацию для чтения в ваших файлах в один список.

lapply(names(linesToSkip), 
       function(x) read.csv(file=x, skip = linesToSkip[x]))
# [[1]]
#   VARIABLE X1 X2
# 1        A  1  2
# 
# [[2]]
#   VARIABLE A1 A2
# 1        A  1  2
# 
# [[3]]
#   VARIABLE Z1 Z2
# 1        A  1  2

Изменить # 1

Альтернативой чтению данных в два раза является чтение его один раз в список, а затем выполнение одного и того же типа обработки:

myRawData <- lapply(list.files(pattern = "myfile.*.csv"), readLines)
lapply(myRawData, function(x) {
  linesToSkip <- grep("^VARIABLE", x)-1
  read.csv(text = x, skip = linesToSkip)
})

Или, если на то пошло:

lapply(list.files(pattern = "myfile.*.csv"), function(x) {
  temp <- readLines(x)
  linesToSkip <- grep("^VARIABLE", temp)-1
  read.csv(text = temp, skip = linesToSkip)
})

Изменить # 2

Как отмечает @PaulHiemstra, вы можете использовать аргумент n, чтобы читать только несколько строк каждого файла в памяти, а не читать весь файл. Таким образом, если вы точно знаете, что в каждом файле содержится не более 20 строк "мусора", если вы используете описанный первый подход, вы можете использовать:

linesToSkip <- sapply(list.files(pattern = "myfile.*.csv"), 
                      function(x) grep("^VARIABLE", readLines(x, n = 20))-1)