使用 lapply 对读入的文件列表应用函数并将输出保存为新的文件列表
Using lapply to apply a function over read-in list of files and saving output as new list of files
我是 R 的新手,对我认为可能是常见操作的操作有点困惑。我有许多文件(57 个,6 列累计约 15 亿行)需要执行基本功能。我能够读取这些文件并执行我不需要的计算,但我在最终输出中绊倒了。我设想该函数一次处理 1 个文件,输出工作文件并移动到下一个文件。
经过计算,我想输出 57 个新的 .txt 文件,这些文件以输入数据最初来自的文件命名。到目前为止,我能够对较小的测试数据集执行计算并吐出 1 个附加的 .txt 文件,但这不是我想要的最终输出。
#list filenames
files <- list.files(path=, pattern="*.txt", full.names=TRUE, recursive=FALSE)
#begin looping process
loop_output = lapply(files,
function(x) {
#Load 'x' file in
DF<- read.table(x, header = FALSE, sep= "\t")
#Call calculated height average a name
R_ref= 1647.038203
#Add column names to .las data
colnames(DF) <- c("X","Y","Z","I","A","FC")
#Calculate return
DF$R_calc <- (R_ref - DF$Z)/cos(DF$A*pi/180)
#Calculate intensity
DF$Ir_calc <- DF$I * (DF$R_calc^2/R_ref^2)
#Output new .txt with calcuated columns
write.table(DF, file=, row.names = FALSE, col.names = FALSE, append = TRUE,fileEncoding = "UTF-8")
})
我最近的代码努力是像这样乱用初始 lapply/sapply 函数:
#begin looping process
loop_output = sapply(names(files),
function(x) {
以及输出行:
#Output new .csv with calcuated columns
write.table(DF, file=paste0(names(DF), "txt", sep="."),
row.names = FALSE, col.names = FALSE, append = TRUE,fileEncoding = "UTF-8")
根据我在 write.table 期间阅读的文件命名功能,输出可能是我尚未与脚本的其余部分完全对齐的关键之一。我一直在查看许多我认为适用的其他问题:
Using lapply to apply a function over list of data frames and saving output to files with different names
Write list of data.frames to separate CSV files with lapply
运气不好。我非常感谢在输入 x 个文件,对每个文件执行相同的功能,然后输出相同的 x 个文件时朝着正确方向前进的任何见解或路径。谢谢你。
使用你的代码,这是一般的想法:
require(purrr)
#list filenames
files <- list.files(path=, pattern="*.txt", full.names=TRUE, recursive=FALSE)
#Call calculated height average a name
R_ref= 1647.038203
dfTransform <- function(file){
colnames(file) <- c("X","Y","Z","I","A","FC")
#Calculate return
file$R_calc <- (R_ref - file$Z)/cos(file$A*pi/180)
#Calculate intensity
file$Ir_calc <- file$I * (file$R_calc^2/R_ref^2)
return(file)
}
output <- files %>% map(read.table,header = FALSE, sep= "\t") %>%
map(dfTransform) %>%
map(write.table, file=paste0(names(DF), "txt", sep="."),
row.names = FALSE, col.names = FALSE, append = TRUE,fileEncoding = "UTF-8")
输出被定向到同一个文件的原因可能是 file = paste0(names(DF), "txt", sep=".")
returns 每次迭代的值相同。也就是说,DF
必须在每次迭代中具有相同的列名,因此 names(DF)
将相同,并且 paste0(names(DF), "txt", sep=".")
将相同。与 append = TRUE
选项一起使用的结果是所有输出都写入同一个文件。
在匿名函数内部,x
是输入文件的名称。您可以不使用 names(DF)
作为输出文件名的基础,而是对该字符串进行一些转换。
示例。
给定
x <- "/foo/raw_data.csv"
在函数内部你可以做这样的事情
infile <- x
outfile <- file.path(dirname(infile), gsub('raw', 'clean', basename(infile)))
outfile
[1] "/foo/clean_data.csv"
然后使用新名称输出,append = FALSE
(除非你需要它是真的)
write.table(DF, file = outfile, row.names = FALSE, col.names = FALSE, append = FALSE, fileEncoding = "UTF-8")
我是 R 的新手,对我认为可能是常见操作的操作有点困惑。我有许多文件(57 个,6 列累计约 15 亿行)需要执行基本功能。我能够读取这些文件并执行我不需要的计算,但我在最终输出中绊倒了。我设想该函数一次处理 1 个文件,输出工作文件并移动到下一个文件。
经过计算,我想输出 57 个新的 .txt 文件,这些文件以输入数据最初来自的文件命名。到目前为止,我能够对较小的测试数据集执行计算并吐出 1 个附加的 .txt 文件,但这不是我想要的最终输出。
#list filenames
files <- list.files(path=, pattern="*.txt", full.names=TRUE, recursive=FALSE)
#begin looping process
loop_output = lapply(files,
function(x) {
#Load 'x' file in
DF<- read.table(x, header = FALSE, sep= "\t")
#Call calculated height average a name
R_ref= 1647.038203
#Add column names to .las data
colnames(DF) <- c("X","Y","Z","I","A","FC")
#Calculate return
DF$R_calc <- (R_ref - DF$Z)/cos(DF$A*pi/180)
#Calculate intensity
DF$Ir_calc <- DF$I * (DF$R_calc^2/R_ref^2)
#Output new .txt with calcuated columns
write.table(DF, file=, row.names = FALSE, col.names = FALSE, append = TRUE,fileEncoding = "UTF-8")
})
我最近的代码努力是像这样乱用初始 lapply/sapply 函数:
#begin looping process
loop_output = sapply(names(files),
function(x) {
以及输出行:
#Output new .csv with calcuated columns
write.table(DF, file=paste0(names(DF), "txt", sep="."),
row.names = FALSE, col.names = FALSE, append = TRUE,fileEncoding = "UTF-8")
根据我在 write.table 期间阅读的文件命名功能,输出可能是我尚未与脚本的其余部分完全对齐的关键之一。我一直在查看许多我认为适用的其他问题:
Using lapply to apply a function over list of data frames and saving output to files with different names
Write list of data.frames to separate CSV files with lapply
运气不好。我非常感谢在输入 x 个文件,对每个文件执行相同的功能,然后输出相同的 x 个文件时朝着正确方向前进的任何见解或路径。谢谢你。
使用你的代码,这是一般的想法:
require(purrr)
#list filenames
files <- list.files(path=, pattern="*.txt", full.names=TRUE, recursive=FALSE)
#Call calculated height average a name
R_ref= 1647.038203
dfTransform <- function(file){
colnames(file) <- c("X","Y","Z","I","A","FC")
#Calculate return
file$R_calc <- (R_ref - file$Z)/cos(file$A*pi/180)
#Calculate intensity
file$Ir_calc <- file$I * (file$R_calc^2/R_ref^2)
return(file)
}
output <- files %>% map(read.table,header = FALSE, sep= "\t") %>%
map(dfTransform) %>%
map(write.table, file=paste0(names(DF), "txt", sep="."),
row.names = FALSE, col.names = FALSE, append = TRUE,fileEncoding = "UTF-8")
输出被定向到同一个文件的原因可能是 file = paste0(names(DF), "txt", sep=".")
returns 每次迭代的值相同。也就是说,DF
必须在每次迭代中具有相同的列名,因此 names(DF)
将相同,并且 paste0(names(DF), "txt", sep=".")
将相同。与 append = TRUE
选项一起使用的结果是所有输出都写入同一个文件。
在匿名函数内部,x
是输入文件的名称。您可以不使用 names(DF)
作为输出文件名的基础,而是对该字符串进行一些转换。
示例。
给定
x <- "/foo/raw_data.csv"
在函数内部你可以做这样的事情
infile <- x
outfile <- file.path(dirname(infile), gsub('raw', 'clean', basename(infile)))
outfile
[1] "/foo/clean_data.csv"
然后使用新名称输出,append = FALSE
(除非你需要它是真的)
write.table(DF, file = outfile, row.names = FALSE, col.names = FALSE, append = FALSE, fileEncoding = "UTF-8")