【问题标题】:How to work with nested for loops in R with same list?如何在具有相同列表的 R 中使用嵌套的 for 循环?
【发布时间】:2021-03-23 03:53:58
【问题描述】:

我正在尝试为我的项目做一些 R 编码。我必须从 R 中的一个目录读取一些 .csv 文件,并且必须将数据框分配为 df_subject1_activity1,我尝试过嵌套循环,但它不起作用。

例如:

我的目录名称是“Test”,我有六个 .csv 文件

subject1activity1.csv, 主题1活动2.csv, 主题1活动3.csv, subject2activity1.csv, 主题2活动2.csv, subject2activity3.csv

现在我想编写代码以在 R 中加载此 .csv 文件并将数据框名称分配为

例如:

subject1activity1 = df_subject1_activity1
subject1activity2 = df_subject1_activity2

....等等使用for循环。

我的预期输出是: df_subject1_activity1 df_subject1_activity2 df_subject1_activity3 df_subject2_activity1 df_subject2_activity2 df_subject2_activity3

我尝试了以下代码: setwd(目录名(getActiveDocumentContext()$path)) 新路径

data_files

for(i in 1:length(data_files)) {
    for(j in 1:4){
        assign(paste0("df_subj",i,"_activity",j)
        read.csv2(paste0(new_path,"/",data_files[i]),sep=",",header=FALSE))
  }
}

我没有得到欲望输出。 R新手可以请任何人帮忙。 谢谢

【问题讨论】:

  • R 中的大多数情况下,您不需要使用循环。您能否展示一些您尝试过的示例代码以及您想要得到的结果?为什么你认为你需要嵌套?你可能想看看 dir() 函数。
  • 嗨,艾琳,我写了下面的代码: data_files
  • 编辑帖子以包含您尝试过的代码。您可以将assign 行更改为assign(paste0("subject",i,"activity",i), read.csv2(....))。尽管不鼓励也不推荐使用assign,但请将数据存储在列表中。

标签: r dataframe loops read.csv nested-for-loop


【解决方案1】:

一种解决方案是使用 vroom 包 (https://www.tidyverse.org/blog/2019/05/vroom-1-0-0/),例如

library(tidyverse)
library(vroom)
library(fs)

files <- fs::dir_ls(glob = "subject_*.csv")
data <- purrr::map(files, ~vroom::vroom(.x))
list2env(data, envir = .GlobalEnv)

# You can also combine all the dataframes if they have the same columns, e.g.
library(data.table)
concat <- data.table::rbindlist(data, fill = TRUE)

【讨论】:

  • 您好,感谢您的回复。但我不应该使用 tidyverse 包。我给出了 6 个列名相同但数据不同的 csv 文件。所以我需要加载 6 个 .csv 文件,这些文件分配给 6 个不同的数据帧。如果我必须为数据框分配一个名称和 1 到 6 个数字,例如将 firstfile.csv 分配给 data.frame1,将 secondfile.csv 分配给 data.frame2,我可以做到这一点。在这种情况下,我可以使用单个 for 循环。但在我的情况下,我的 firstfile.csv 分配给 subject1_activity1_df 然后 secondfile.csv 分配给 subject1_activity2_df 等等。所以我无法在这种情况下使用单个 for 循环分配数据帧名称
【解决方案2】:

你快到了。与往常一样,如果您不确定,使用更多行清晰地编码绝不是一个坏主意。


data_files <- list.files(pattern=".csv", full.names=TRUE) # Identify file names data_files

for( data_file in data_files) {

    ## check that the data file matches our expected pattern:
    if(!grepl( "subject[0-9]activity[0-9]", basename(data_file) )) {
        warning( "skiping file ", basename(data_file) )
        next
    }

    ## start creating the variable name from the filename

    ## remove the .csv extension
    var.name <- sub( "\\.csv", "", basename(data_file), ignore.case=TRUE )

    ## prepend 'df' and introduce underscores:
    var.name <- paste0(
        "df",
        gsub( "(subject|activity)", "_\\1", var.name ) ## this looks for literal 'subject' and 'acitivity' and if found, adds an underscore in front of it
    )

    ## now read the file
    data.from.file <- read.csv2( data_file )

    ## and assign it to our variable name
    assign( var.name, data.from.file )

}

我没有要测试的文件,但如果上述方法失败,您应该能够逐行运行代码并轻松查看哪里开始出错。

【讨论】:

  • 非常感谢......上面的代码对我有用。非常感谢您为理解代码提供的提示和 cmets。
  • np,很高兴!
猜你喜欢
  • 2016-10-21
  • 2021-05-22
  • 1970-01-01
  • 2019-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多