R循环中的变量作为函数的结果

Joh*_*aph -1 loops r

我在将文件名作为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="")
                }
Run Code Online (Sandbox Code Playgroud)

它只生成一个对象:aname如果我使用以下内容:

for (a in files) { c(strsplit(basename(a), "\\.")[[1]][1]) <- read.table(a,header=TRUE,
                        sep="\t",comment.char="")
                }
Run Code Online (Sandbox Code Playgroud)

它产生:找不到函数"c < - ".但如果我这样做

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

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

Rei*_*son 6

问题不在于处理文件名,而在于您编写循环的方式.基本上你在做:

for(i in list.of.files) {
  foo <- processName(i)
  foo <- read.table(foo)
}
Run Code Online (Sandbox Code Playgroud)

当这样看时,很明显,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
Run Code Online (Sandbox Code Playgroud)

让列表中包含的对象是一个有用的功能,所以你不要让所有那些对象晃来晃去.由于它们包含在列表中,因此您可以使用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="")
}
Run Code Online (Sandbox Code Playgroud)

了解?assign更多.