读取多个 ENVI 文件并将它们合并到一个 csv 中
read multiple ENVI files and combine them in one csv
我在使用 R 方面还很陌生,但正在努力完成这项工作。我有几十个 ENVI 光谱数据集存储在一个目录中。每个数据集分为两个文件。它们都有相同的名称约定,即:
- ID_YYYYMMDD_350-200nm.asr
- ID_YYYYMMDD_350-200nm.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")
您可以在此处找到示例数据集:Sample dataset
我处理大量实验室数据,我可以依赖可靠格式的输出文件(相同的列顺序、列名称、header 格式等)。所以这是假设您拥有的 .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
,我认为这是处理日期和时间的更好方法。
我在使用 R 方面还很陌生,但正在努力完成这项工作。我有几十个 ENVI 光谱数据集存储在一个目录中。每个数据集分为两个文件。它们都有相同的名称约定,即:
- ID_YYYYMMDD_350-200nm.asr
- ID_YYYYMMDD_350-200nm.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")
您可以在此处找到示例数据集:Sample dataset
我处理大量实验室数据,我可以依赖可靠格式的输出文件(相同的列顺序、列名称、header 格式等)。所以这是假设您拥有的 .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
,我认为这是处理日期和时间的更好方法。