Прочитать несколько файлов ENVI и объединить их в один CSV

Я довольно новичок в работе с R, но пытаюсь сделать это. У меня есть десятки наборов спектральных данных ENVI, хранящихся в каталоге. Каждый набор данных разделен на два файла. Все они имеют одинаковое соглашение об именах, то есть:

  • ID_YYYYMMDD_350-200nm.asr
  • ID_YYYYMMDD_350-200nm.hdr

Задача состоит в том, чтобы прочитать набор данных, добавить два столбца (идентификатор и дату из имени файла) и сохранить результаты в *.csv-файле. Я получил это, чтобы работать для одного файла (жестко).

library(caTools)

setwd("D:/some/path/software_scripts")

### filename without extension
name <- "011a_20100509_350-2500nm"

### split filename in area-id and date
flaeche<-substr(name, 0, 4)
date <- as.Date((substr(name,6,13)),"%Y%m%d")

### get values from ENVI-file in a matrix
spectrum <- read.ENVI(paste(name,".esl", sep = ""), headerfile=paste(name,".hdr", sep=""))

### add columns
spectrum <- cbind(Flaeche=flaeche,Datum=as.character(date),spectrum)


### CSV-Dataset with all values
write.csv(spectrum, file = name,".csv", sep=",")

Я хочу объединить все доступные файлы в один файл *.csv. Я знаю, что должен использовать list.files, но не знаю, как реализовать функцию read.ENVI и добавить полученные матрицы в CSV.


Обновить:

library(caTools)

setwd("D:/some/path/mean")

files <- list.files() # change or leave totally empty if setwd() put you in the right spot

all_names <- sub("^([^.]*).*", "\\1", files) # strip off extensions

name <- unique(all_names) # get rid of duplicates from .esl and .hdr

# wrap your existing code in a function
mungeENVI <- function(name) {

  # split filename in area-id and date
  flaeche<-substr(name, 0, 4)
  date <- as.Date((substr(name,6,13)),"%Y%m%d")

  # get values from ENVI-file in a matrix
  spectrum <- read.ENVI(paste(name,".esl", sep = ""), headerfile=paste(name,".hdr", sep=""))

  # add columns
  spectrum <- cbind(Flaeche=flaeche,Datum=as.character(date),spectrum)
  return(spectrum)
}

# use lapply to 'loop' over each name
list_of_ENVIs <- lapply(name, mungeENVI) # returns a list

# use do.call(rbind, x) to turn it into a big data.frame
final_df <- do.call(rbind, list_of_ENVIs)

# now write output
write.csv(final_df, "all_results.csv")

Вы можете найти образец набора данных здесь: Пример набора данных

1 ответ

Решение

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

В любом случае вот идея:

library(caTools)
library(lubridate)
library(magrittr)

setwd("~/Binfo/TST/Stack/") # adjust as needed

files <- list.files("data/", full.name = T) # adjust as needed
all_names <- gsub("\\.\\D{3}", "", files) # strip off extensions
names1 <- unique(all_names) # get rid of duplicates

# wrap your existing code in a function
mungeENVI <- function(name) {
    # split filename in area-id and date
    f <- gsub(".*\\/(\\d{3}\\D)_.*", "\\1", name)
    d <- gsub(".*_(\\d+)_.*", "\\1", name) %>% ymd()
    # get values from ENVI-file in a matrix
    spectrum <- read.ENVI(paste(name,".esl", sep = ""), headerfile=paste(name,".hdr", sep=""))
    # add columns
    spectrum <- cbind(Flaeche=f,Datum= as.character(d),spectrum)
    return(spectrum)
}
# use lapply to 'loop' over each name
list_of_ENVIs <- lapply(names1, mungeENVI) # returns a list

# use do.call(rbind, x) to turn it into a big data.frame
final_df <- do.call(rbind, list_of_ENVIs)
# now write output
write.csv(final_df, "data/all_results.csv")

Дайте мне знать, если у вас есть какие-либо проблемы, и мы пошли оттуда. Приветствия.

Я немного отредактировал свой ответ. Думаю, проблема в том, list.files() это должно было иметь аргумент full.name = T, Я также настроил ваш метод разбора, чтобы он был немного более оборонительным и использовал выражения захвата grep. Я проверил код с вашими двумя примерами файлов (на самом деле 4), но я могу построить большую матрицу (66743 элементов). Также я использовал lubridateЯ думаю, что это лучший способ работать с датами и временем.

Другие вопросы по тегам