我在将文件名作为变量处理为R
中的循环时遇到问题files <- list.files(pattern = "*.tab",full.name=T)
for (a in files) { aname <- strsplit(basename(a), "\\.")[[1]][1]
aname <- read.table(a,header=TRUE, sep="\t",comment.char="")
}
它只生成一个对象:aname
,如果我使用以下内容:
for (a in files) { c(strsplit(basename(a), "\\.")[[1]][1]) <- read.table(a,header=TRUE,
sep="\t",comment.char="")
}
它产生:找不到函数“c&lt; - ”。但是如果我做的话
for (a in files) { aname <- strsplit(basename(a), "\\.")[[1]][1]
print(aname)
}
输出是没有扩展名的文件列表,如预期的那样。所以,问题是:如何使函数的结果成为变量名? 谢谢!
答案 0 :(得分:6)
问题不在于处理文件名,而在于您编写循环的方式。基本上你在做:
for(i in list.of.files) {
foo <- processName(i)
foo <- read.table(foo)
}
当这样看时,显然foo
在循环的每次迭代中被写入两次,因此只能获取最后一次read.table()
调用的值。
您要做的是在进入循环之前为文件列表分配存储空间,然后随时填写该列表。例如:
aname <- vector("list", length = length(files))
fnames <- character(length(files))
for(i in seq_along(aname)) {
fnames[i] <- strsplit(basename(files[i]), "\\.")[[1]][1]
aname[i] <- read.table(a, header=TRUE, sep="\t", comment.char="")
}
names(aname) <- fnames
让列表中包含的对象是一个有用的功能,所以你不要让所有那些对象都在晃动。由于它们包含在列表中,因此您可以使用lapply()
或类似操作对每个对象进行操作。
如果你真的想要一个单独的对象,其文件名没有扩展名作为所有文件的名称,那么你可以使用assign()
,但我不推荐它
files <- list.files(pattern = "*.tab", full.name=TRUE)
for (a in files) {
aname <- strsplit(basename(a), "\\.")[[1]][1]
assign(aname, read.table(a, header=TRUE, sep="\t", comment.char="")
}
有关详情,请参阅?assign
。