对于R中的循环仅适用于最后一个索引号

时间:2016-05-27 19:19:00

标签: r

所以我正在为R课程开设Coursera课程。

我使用for循环尝试创建一个组合332 csv文件数据的数据框。 for循环仅返回最后一个(第332个)csv文件的数据帧。 我做错了什么?

corr <- function(directory, threshold = 0) {

  files <- Sys.glob("specdata//*.csv")

  ## Create empty numeric vector to append the nitrate values
  nitr <- numeric()
  ## Create empty numeric vector to append the sulfate values
  sulf <- numeric()

  for (j in 1:length(files)) {
    read.data <- read.csv(files[j])
  }
}

3 个答案:

答案 0 :(得分:3)

  1. directorythreshold被定义为参数但未使用。
  2. nitrsulf已创建但未使用
  3. 通常使用
  4. 来获取list.files("specdata", pattern=".csv", full.names=TRUE)这样的文件列表
  5. 对于每次迭代,都会读取files[j](并替换以前的迭代),但当时没有任何操作。
  6. 此外,您的功能应该返回一些内容。
  7. 我认为你真的不需要一个功能,下面的代码应该可以胜任。
  8. ```

    files <- list.files("specdata", pattern=".csv", full.names=TRUE)
    res <- vector("list", length(files))
    for (j in 1:length(files)) { # or seq_along(files)
      res[[j]] <- read.csv(files[j])
    }
    res
    

    ```

    实际上这是:

    lapply(list.files("specdata", pattern=".csv", full.names=TRUE), read.csv)
    

    可能会起到同样好的作用,而且不那么冗长,并且具有可爱的R重音。如果您需要read.csv的更多参数,例如header=TRUE,您可以在函数名称后面添加它们(命名和逗号分隔):

    lapply(list.files("specdata", pattern=".csv", full.names=TRUE), read.csv, header=TRUE)
    

答案 1 :(得分:3)

这很容易,你在循环的每次迭代中都会覆盖read.data。你可能想要这样的东西:

files <- Sys.glob("specdata//*.csv")

## Create empty numeric vector to append the nitrate values
nitr <- numeric()
## Create empty numeric vector to append the sulfate values
sulf <- numeric()

out <- vector("list")

for (j in 1:length(files)) {
  out[[j]] <- read.csv(files[j])
}

调试for循环的好方法是将j设置为1,遍历循环体,然后将其设置为2并执行相同的操作。此外,您可能希望使用seq_along(files)而不是1:length(files),当文件长度为0时,前者可能会给您带来不良结果。

答案 2 :(得分:0)

我相信这是最快的方法。这也将显示正在完成的任务的进度条。

library(data.table)
library(pbapply)


# get file names
  files <- list.files("c:/your_folder", pattern=".csv", full.names=TRUE)

# read and pile all files 
  dt <- rbindlist(pblapply(files, fread))