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

#r #csv #envi

#r #csv #envi

Вопрос:

Я довольно новичок в работе с 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, но понятия не имею, как реализовать чтение.Функция 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. вам нужно собрать все ваши файлы в один большой фрейм данных, что-то вроде этого lapply(list.files(dir), read.ENVI) %>% do.call(rbind,.)

2. спасибо за ваш ответ, но для меня он все еще слишком загадочный.

3. не беспокойтесь, приятель, дайте мне пару минут, и я загружу для вас более подробный ответ

Ответ №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 , я думаю, что это лучший способ работы с датами и временем.

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

1. Привет, спасибо, что вернулись к этому! Мне пришлось внести некоторые незначительные изменения в расширение — удалить и удалить дубликаты, что сейчас работает фантастически. К сожалению, произошла ошибка: Error in read.ENVI(paste(name, ".esl", sep = ""), headerfile = paste(name, : read.ENVI: Could not open input header file: .hdr Called from: read.ENVI(paste(name, ".esl", sep = ""), headerfile = paste(name, ".hdr", sep = ""))

2. Изменения: all_names <- sub("^([^.]*).*", "\1", files) # strip off extensions name <- unique(all_names) # get rid of duplicates from .esl and .hdr

3. Можете ли вы проверить переменную names и посмотреть, есть ли там пустая строка?

4. К сожалению, я не смог найти ни одной пустой строки, но обновил вопрос текущим кодом (вкл. незначительные изменения) и образец набора данных.

5. Отредактировал мой ответ на рабочее решение с вашими примерами файлов, дайте мне знать, если это сработает для вас…