对某个文件夹中的所有 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