在某个文件夹中的所有csv文件上应用函数

时间:2015-01-28 17:15:51

标签: r statistics

我正在从某个文件夹中读取csv文件,这些文件都具有相同的结构。此外,我创建了一个向dataFrame添加特定值的函数。

我创建了"文件夹阅读" - 部分并创建了该功能。但是,我现在需要将这两者相互连接起来。这就是我遇到问题的地方:

这是我的代码:

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)

如何在我的addValue()构造中应用#1.reading R files函数?有什么建议吗?

感谢您的回答!

更新

在尝试示例代码时,我得到:

+   }
+   ## 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

有什么建议吗?

1 个答案:

答案 0 :(得分:1)

您的代码存在一些问题(例如,您的函数中的x从未定义,并且在调用addValue之间不会保留,因此我猜测这是一个切碎的 - 真实代码的下载版本,你仍然有剩余的残余。我不会冗长地分开,而是提供我自己建议的代码和一些指示。

函数addValue看起来好像更改了data.frame,但我不会猜到(至少名字)它也会将文件写入磁盘(并且可能超过 - 写一个现有的文件)。

我猜你正试图(1)读取文件,(2)&#34;增值&#34;它,(3)将它分配给一个全局变量,(4)将它写入磁盘。第三个可能有问题(并且对一些程序员有争议),但我现在就把它留下。

除非写入磁盘是您的想法所固有的&#34;增加价值&#34;对于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)
}

请注意,它不会覆盖全局变量。这可能是一个烦人的检查,但如果您不小心运行此部分代码,将使您不会丢失数据。

为全局地址空间分配大量变量的另一种方法是将所有保存到单个列表中。假设它们是相同的格式,您可能会使用相同(或非常相似)的分析方法处理它们,因此将它们全部放在一个列表中将有助于实现这一点。跟踪不同变量名称的替代方案可能很烦人。

## 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