对某个文件夹中的所有 csv 文件应用函数
Applying a function on all csv files from a certain folder
我正在读取某个文件夹中的 csv 文件,它们都具有相同的结构。此外,我创建了一个函数,它向数据帧添加了一定的值。
我创建了 "folder reading" - 部分并创建了函数。但是,我现在需要将这两者相互联系起来。这是我遇到问题的地方:
这是我的代码:
addValue <- function(valueToAdd, df.file, writterPath) {
df.file$result <- df.file$Value + valueToAdd
x <- x + 1
df.file <- as.data.frame(do.call(cbind, df.file))
fullFilePath <- paste(writterPath, x , "myFile.csv", sep="")
write.csv(as.data.frame(df.file), fullFilePath)
}
#1.reading R files
path <- "C:/Users/RFiles/files/"
files <- list.files(path=path, pattern="*.csv")
for(file in files)
{
perpos <- which(strsplit(file, "")[[1]]==".")
assign(
gsub(" ","",substr(file, 1, perpos-1)),
read.csv(paste(path,file,sep="")))
}
#2.appyling function
writterPath <- "C:/Users/RFiles/files/results/"
addValue(2, sys, writterPath)
如何在我的 #1.reading R files
构造中应用 addValue()
函数?有什么建议吗?
感谢您的回答!
更新
尝试示例代码时,我得到:
+ }
+ ## If you really need to change filenames with numbers,
+ newfname <- file.path(npath, paste0(x, basename(fname)))
+ ## otherwise just use `file.path(npath, basename(fname))`.
+
+ ## (4) Write back to a different file location:
+ write.csv(newdat, file = newfname, row.names = FALSE)
+ }
Error in `$<-.data.frame`(`*tmp*`, "results", value = numeric(0)) :
replacement has 0 rows, data has 11
有什么建议吗?
你的代码有几个问题(例如,你的函数中的 x
从未定义并且在调用 addValue
之间没有保留),所以我猜这是一个切碎的-down 版本的真实代码,你仍然有剩余。我不会冗长地把它拆开,而是提供我自己的建议代码和一些提示。
函数 addValue
看起来很适合更改 data.frame,但我不会猜到(至少根据名称)它也会将文件写入磁盘(并可能覆盖现有文件)。
我猜您正在尝试 (1) 读取一个文件,(2) "add value" 给它,(3) 将它分配给一个全局变量,以及 (4) 将它写入磁盘。第三个可能会有问题(并且会引起一些程序员的争议),但我暂时保留它。
除非写入磁盘是您将 "adding value" 写入 data.frame 的固有想法,否则我建议您将 #2 与 #4 分开。以下是您的代码的建议替代方案:
addValue <- function(valueToAdd, df) {
df$results <- df$Value + valueToAdd
## more stuff here?
return(df)
}
opath <- 'c:/Users/RFiles/files/raw' # notice the difference
npath <- 'c:/Users/RFiles/files/adjusted'
files <- list.files(path = opath, pattern = '*.csv', full.names = TRUE)
x <- 0
for (fname in files) {
x <- x + 1
## (1) read in and (2) "add value" to it
dat <- read.csv(fname)
newdat <- addValue(2, dat)
## (3) Conditionally assign to a global variable:
varname <- gsub('\.[^.]*$', '', basename(fname))
if (! exists(varname)) {
assign(x = varname, value = newdat)
} else {
warning('variable exists, did not overwrite: ', varname)
}
## If you really need to change filenames with numbers,
newfname <- file.path(npath, paste0(x, basename(fname)))
## otherwise just use `file.path(npath, basename(fname))`.
## (4) Write back to a different file location:
write.csv(newdat, file = newfname, row.names = FALSE)
}
注意它不会覆盖全局变量。这可能是一个烦人的检查,但如果您不小心 运行 这部分代码,可以防止您丢失数据。
将大量变量分配给全局地址 space 的另一种方法是将它们的 所有 保存到一个列表中。假设它们是相同的格式,您可能会使用相同(或非常相似)的分析方法来处理它们,因此将它们全部放在一个列表中将有助于实现这一点。跟踪不同的变量名称的替代方法可能很烦人。
## addValue as defined previously
opath <- 'c:/Users/RFiles/files/raw'
npath <- 'c:/Users/RFiles/files/adjusted'
ofiles <- list.files(path = opath, pattern = '*.csv', full.names = TRUE)
nfiles <- file.path(npath, basename(ofiles))
dats <- mapply(function(ofname, nfname) {
dat <- read.csv(ofname)
newdat <- addValue(2, dat)
write.csv(newdat, file = nfname, row.names = FALSE)
newdat
}, ofiles, nfiles, SIMPLIFY = FALSE)
length(dats) # number of files
names(dats) # one for each file
我正在读取某个文件夹中的 csv 文件,它们都具有相同的结构。此外,我创建了一个函数,它向数据帧添加了一定的值。
我创建了 "folder reading" - 部分并创建了函数。但是,我现在需要将这两者相互联系起来。这是我遇到问题的地方:
这是我的代码:
addValue <- function(valueToAdd, df.file, writterPath) {
df.file$result <- df.file$Value + valueToAdd
x <- x + 1
df.file <- as.data.frame(do.call(cbind, df.file))
fullFilePath <- paste(writterPath, x , "myFile.csv", sep="")
write.csv(as.data.frame(df.file), fullFilePath)
}
#1.reading R files
path <- "C:/Users/RFiles/files/"
files <- list.files(path=path, pattern="*.csv")
for(file in files)
{
perpos <- which(strsplit(file, "")[[1]]==".")
assign(
gsub(" ","",substr(file, 1, perpos-1)),
read.csv(paste(path,file,sep="")))
}
#2.appyling function
writterPath <- "C:/Users/RFiles/files/results/"
addValue(2, sys, writterPath)
如何在我的 #1.reading R files
构造中应用 addValue()
函数?有什么建议吗?
感谢您的回答!
更新
尝试示例代码时,我得到:
+ }
+ ## If you really need to change filenames with numbers,
+ newfname <- file.path(npath, paste0(x, basename(fname)))
+ ## otherwise just use `file.path(npath, basename(fname))`.
+
+ ## (4) Write back to a different file location:
+ write.csv(newdat, file = newfname, row.names = FALSE)
+ }
Error in `$<-.data.frame`(`*tmp*`, "results", value = numeric(0)) :
replacement has 0 rows, data has 11
有什么建议吗?
你的代码有几个问题(例如,你的函数中的 x
从未定义并且在调用 addValue
之间没有保留),所以我猜这是一个切碎的-down 版本的真实代码,你仍然有剩余。我不会冗长地把它拆开,而是提供我自己的建议代码和一些提示。
函数 addValue
看起来很适合更改 data.frame,但我不会猜到(至少根据名称)它也会将文件写入磁盘(并可能覆盖现有文件)。
我猜您正在尝试 (1) 读取一个文件,(2) "add value" 给它,(3) 将它分配给一个全局变量,以及 (4) 将它写入磁盘。第三个可能会有问题(并且会引起一些程序员的争议),但我暂时保留它。
除非写入磁盘是您将 "adding value" 写入 data.frame 的固有想法,否则我建议您将 #2 与 #4 分开。以下是您的代码的建议替代方案:
addValue <- function(valueToAdd, df) {
df$results <- df$Value + valueToAdd
## more stuff here?
return(df)
}
opath <- 'c:/Users/RFiles/files/raw' # notice the difference
npath <- 'c:/Users/RFiles/files/adjusted'
files <- list.files(path = opath, pattern = '*.csv', full.names = TRUE)
x <- 0
for (fname in files) {
x <- x + 1
## (1) read in and (2) "add value" to it
dat <- read.csv(fname)
newdat <- addValue(2, dat)
## (3) Conditionally assign to a global variable:
varname <- gsub('\.[^.]*$', '', basename(fname))
if (! exists(varname)) {
assign(x = varname, value = newdat)
} else {
warning('variable exists, did not overwrite: ', varname)
}
## If you really need to change filenames with numbers,
newfname <- file.path(npath, paste0(x, basename(fname)))
## otherwise just use `file.path(npath, basename(fname))`.
## (4) Write back to a different file location:
write.csv(newdat, file = newfname, row.names = FALSE)
}
注意它不会覆盖全局变量。这可能是一个烦人的检查,但如果您不小心 运行 这部分代码,可以防止您丢失数据。
将大量变量分配给全局地址 space 的另一种方法是将它们的 所有 保存到一个列表中。假设它们是相同的格式,您可能会使用相同(或非常相似)的分析方法来处理它们,因此将它们全部放在一个列表中将有助于实现这一点。跟踪不同的变量名称的替代方法可能很烦人。
## addValue as defined previously
opath <- 'c:/Users/RFiles/files/raw'
npath <- 'c:/Users/RFiles/files/adjusted'
ofiles <- list.files(path = opath, pattern = '*.csv', full.names = TRUE)
nfiles <- file.path(npath, basename(ofiles))
dats <- mapply(function(ofname, nfname) {
dat <- read.csv(ofname)
newdat <- addValue(2, dat)
write.csv(newdat, file = nfname, row.names = FALSE)
newdat
}, ofiles, nfiles, SIMPLIFY = FALSE)
length(dats) # number of files
names(dats) # one for each file