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

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

  • ID_ГГГГММДД_350-200нм.asr
  • ID_ГГГГММДД_350-200нм.hdr

Задача - прочитать набор данных, добавить два столбца (ID и дату из имени файла) и сохранить результаты в файле * .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")

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


person dan_ke    schedule 06.10.2016    source источник
comment
вам нужно собрать все файлы в один большой фрейм данных, примерно так lapply(list.files(dir), read.ENVI) %>% do.call(rbind,.)   -  person Nate    schedule 06.10.2016
comment
спасибо за ваш ответ, но для меня это все еще слишком загадочно.   -  person dan_ke    schedule 06.10.2016
comment
не волнуйся, приятель, дай мне пару минут, и я загружу для тебя более подробный ответ   -  person Nate    schedule 06.10.2016


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

person Nate    schedule 06.10.2016
comment
Привет, спасибо, что вернулись к этому вопросу! Мне пришлось внести некоторые незначительные изменения в удаление расширений и дубликатов, что сейчас работает фантастически. К сожалению, есть ошибка: 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 = "")) - person dan_ke; 07.10.2016
comment
изменения: all_names <- sub("^([^.]*).*", "\\1", files) # strip off extensions name <- unique(all_names) # get rid of duplicates from .esl and .hdr - person dan_ke; 07.10.2016
comment
Можете ли вы проверить переменную name и увидеть, есть ли там пустая строка? - person Nate; 07.10.2016
comment
К сожалению, я не смог найти ни одной пустой строки, но обновил вопрос с помощью текущего кода (включая незначительные изменения) и образца набора данных. - person dan_ke; 08.10.2016
comment
Отредактировал свой ответ на рабочее решение с вашими файлами примеров, дайте мне знать, работает ли оно для вас ... - person Nate; 09.10.2016
comment
Привет, Натан, спасибо за твои усилия. Я действительно ценю это. При попытке запустить ваш код у меня возникла следующая ошибка: > # use lapply to 'loop' over each name > list_of_ENVIs <- lapply(names1, mungeENVI) # returns a list Error in FUN(X[[i]], ...) : could not find function "%>%" Called from: FUN(X[[i]], ...) - person dan_ke; 10.10.2016
comment
Ой, мой плохой %>% от library(magrittr). Надеюсь, это последний кусок :) - person Nate; 10.10.2016