【问题标题】:Function to read in multiple delimited text files读取多个分隔文本文件的功能
【发布时间】:2014-12-19 11:55:22
【问题描述】:

使用this answer,我创建了一个应该读取目录中所有文本数据集的函数:

read.delims = function(dir, sep = "\t"){

  # Make a list of all data frames in the "data" folder
  list.data = list.files(dir, pattern = "*.(txt|TXT|csv|CSV)")

  # Read them in
  for (i in 1:length(list.data)) {
    assign(list.data[i],
           read.delim(paste(dir, list.data[i], sep = "/"),
                      sep = sep))
  }

}

但是,即使指定目录中有 .txt 和 .csv 文件,也不会创建 R 对象(我猜这是因为我在函数中使用了 read.delim)。如何纠正这个问题?

【问题讨论】:

  • 你的函数没有返回值。尝试在最后添加return(list.data)
  • 添加return(list.data) 会打印出列表,但不会创建任何数据框。

标签: r function csv


【解决方案1】:

您可以在分配中添加参数envir,如下所示:

read.delims = function(dir, sep = "\t"){

  # Make a list of all data frames in the "data" folder
  list.data = list.files(dir, pattern = "*.(txt|TXT|csv|CSV)")

  # Read them in
  for (i in 1:length(list.data)) {
    assign(list.data[i],
           read.delim(paste(dir, list.data[i], sep = "/"),
                      sep = sep),
          envir=.GlobalEnv)
  }
}

这样做,您的对象将在全局环境中创建,而不仅仅是在函数环境中

【讨论】:

  • 正是我想要的(尽管@Simon 的评论有效)。
  • 太棒了!如果能帮到你我很高兴:-)
【解决方案2】:

正如我在评论中所说,分配后需要return() 一个值。不过,我并没有真正看到使用 assign() 的意义,所以这里有一个简单的 for 循环,假设您希望输出是数据帧列表。

请注意,为了个人方便,我将阅读功能更改为read.table()。您可能需要调整它。

read.delims <- function(dir, sep = "\t"){

  # Make a list of all data frames in the "data" folder
  list.data <- list.files(dir, pattern = "*.(txt|TXT|csv|CSV)")
  list.out <- as.list(1:length(list.data))

  # Read them in
  for (i in 1:length(list.data)) {
    list.out[[i]] <- read.table(paste(dir, list.data[i], sep = "/"), sep = sep)
  }
  return(list.out)
}

也许您还应该在正则表达式中添加$

干杯。

【讨论】:

  • 我觉得我们到了某个地方!现在该函数打印出数据帧(即文件的内容)。但它仍然没有在我的工作区中创建任何对象。理想情况下,它应该创建一组对象,其名称与创建它们的文件名相同(没有文件扩展名)。它可以分解列表并从中创建单独的数据框吗?还是必须是函数之外的第二步?
  • 好的,我现在终于明白了你想要实现的目标。您想为每个文件创建一个对象...实际上我认为这是一种不好的做法,因为您以这种方式将工作区中的对象弄得一团糟,而且很容易忘记它们。最好将它们保存到一个列表中,将它们全部保存在一个对象中。上面的函数正是这样做的。只需将输出分配给一个对象,例如datasets &lt;- read.delims(...),您将拥有一个包含所有数据集的列表。每个数据集都可以通过例如datasets[[1]] 访问第一个数据集。
  • 将它们全部放在一个列表中不仅是“更好的做法”,而且也更方便。例如,使用do.call(rbind, ...) 很容易将它们绑定在一起(如果它们共享相同的格式),或者使用lapply() 在所有数据集中执行共同的测试。编辑:如果你真的想要单独的对象,那么看看下面 CathG 的建议。它修复了你的 assign() 调用,并且你得到了单独的对象。
  • 正式注明。此功能旨在加载已为后续分析准备的数据集。由于以这种方式创建的每个对象在此过程中都有自己的预谋角色,因此消除了不必要的混乱风险。但是,我会记住您的评论(以及关于lapply 等的有用评论)
猜你喜欢
  • 1970-01-01
  • 2019-12-07
  • 2021-03-27
  • 1970-01-01
  • 1970-01-01
  • 2019-09-05
  • 1970-01-01
  • 1970-01-01
  • 2015-05-21
相关资源
最近更新 更多