#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. Отредактировал мой ответ на рабочее решение с вашими примерами файлов, дайте мне знать, если это сработает для вас…