希望我能够很好地解释我的问题以获得答案 - 任何帮助都将受到赞赏。
我有一个数字,如果数据文件,我需要合并为一个。我使用for循环来执行此操作并添加一个列,指示它是哪个文件。
在这种情况下,有6个文件,每个文件最多包含100个数据条目。
当有6个文件时,我没有问题让它运行。
但是当我遇到问题时,我就会有更少的问题。
我想要做的是使用for循环来测试文件,并使用for循环变量来组合一个引用存在的文件的向量。
我似乎无法获取新变量来组合for循环变量的新值,因为它通过循环。
以下是我目前编写的示例代码。
for ( rloop1 in 1 : 6) {
ReadFile=paste(rloop1,SampleName,"_",FileName,"_Stats.csv", sep="")
if (file.exists(ReadFile))
**files_found <- c(rloop1)**
}
我正在寻找的是files_found将包含那些文件,其中1 ... 6对找到的文件有效。
此致 史蒂夫
答案 0 :(得分:7)
列出要加载的文件可能会更好,然后循环遍历该列表以加载它们。 list.files
是你的朋友。我们可以使用正则表达式仅列出以"_Stats.csv"
结尾的文件。例如,在我当前的工作目录中,我有以下文件:
$ ls | grep Stats
bar_Stats.csv
foobar_Stats.csv
foobar_Stats.csv.txt
foo_Stats.csv
其中只有三个是我要加载的csv文件(.txt
文件与您显示的模式不匹配)。我们可以使用list.files()
获取这些文件名:
> list.files(pattern = "_Stats.csv$")
[1] "bar_Stats.csv" "foo_Stats.csv" "foobar_Stats.csv"
然后你可以遍历它并读取文件。例如:
fnames <- list.files(pattern = "_Stats.csv$")
for(i in seq_along(fnames)) {
assign(paste("file_", i, sep = ""), read.csv(fnames[i]))
}
这将在全局工作空间中创建一系列对象file_1
,file_2
,file_3
等。如果您想要列表中的文件,则可以lapply
代替fnames
:
lapply(fnames, read.csv)
如果合适,do.call
可能有助于合并列表中的文件:
do.call(rbind, lapply(fnames, read.csv))
答案 1 :(得分:4)
如Henrik所示,使用list.files()的方法要短得多。如果您不熟悉正则表达式(请参阅?regex
),您可以这样做。
n <- 6
Fnames <- paste(1:n,SampleName,"_",FileName,"Stats.csv",sep="")
Filelist <- Fnames[file.exists(Fnames)]
完全等同。 paste
和file.exists
都是矢量化函数,因此您最好使用它。无论如何都不需要for循环。
要获取文件名的数量(假设这是唯一的数字),您可以这样做:
gsub("^[:digit:]","", Filelist)
另见?regex
答案 2 :(得分:3)
我认为有更好的解决方案(例如,您可以使用list.files()
扫描文件夹然后循环返回对象的长度),但这应该(我没试过)做的伎俩(使用您的示例代码):
files.found <- ""
for (rloop1 in 1 : 6) {
ReadFile=paste(rloop1,SampleName,"_",FileName,"_Stats.csv", sep="")
if (file.exists(ReadFile)) files_found <- c(files.found, rloop1)
}
或者,您可以通过以下方式获取fileNames(索引除外):
files.found <- ""
for (rloop1 in 1 : 6) {
ReadFile=paste(rloop1,SampleName,"_",FileName,"_Stats.csv", sep="")
if (file.exists(ReadFile)) files_found <- c(files.found, ReadFile)
}
最后,在你的情况下,list.files
看起来像这样:
files.found <- list.files(pattern = "[[:digit:]]_SampleName_FileName_Stats.csv")