-1

我在 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<-”。但如果我这样做

for (a in files) { aname <- strsplit(basename(a), "\\.")[[1]][1]
                   print(aname)
                }

正如预期的那样,输出是一个没有扩展名的文件列表。所以,问题是:如何使函数的结果成为变量名?谢谢!

4

1 回答 1

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更多。

于 2012-11-14T21:54:05.510 回答