首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >减少对嵌套for循环R中文件的不必要重复读取

减少对嵌套for循环R中文件的不必要重复读取
EN

Stack Overflow用户
提问于 2020-04-19 08:35:52
回答 2查看 32关注 0票数 0

我正在写一些R代码来处理成对的文件,一个Excel和一个csv (Imotions.txt)。我需要从Excel中提取一列,并将其成对合并到csv中。下面是我的简短脚本:我的脚本现在是多项式时间,并且不断重复嵌套的for循环的主体4次,而不是只重复一次。

基本上,有没有一种通用的方式来考虑在一组成对的文件上运行一些代码,我可以将这些文件翻译成这种语言和其他语言?

代码语言:javascript
复制
excel_files <- list.files(pattern = ".xlsx"    , full.names = TRUE)
imotion_files <-list.files(pattern = 'Imotions.txt', full.names = TRUE)

for (imotion_file in imotion_files) {
  for (excel_file in excel_files) {

    filename <- paste(sub("_Imotions.txt", "", imotion_file))

    raw_data <- extract_raw_data(imotion_file)

    event_data <- extract_event_data(imotion_file)


    #convert times to milliseconds
    latency_ms <- as.data.frame(
      sapply(
        df_col_only_ones$latency,
        convert_to_ms,
        raw_data_first_timestamp = raw_data_first_timestamp
      )
    )

    #read in paradigm data
    paradigm_data <- read_excel(path = excel_file, range = "H30:H328")

    merged <- bind_cols(latency_ms, paradigm_data)

    print(paste("writing = ", filename))
        write.table(
        merged,
        file = paste(filename, "_EVENT", ".txt", sep = ""),
        sep = '\t',
        col.names = TRUE,
        row.names = FALSE,
        quote = FALSE
        )
  }
}
EN

回答 2

Stack Overflow用户

发布于 2020-04-19 08:47:17

对于一些操作还不完全清楚。这是tidyverse中的一个选项

代码语言:javascript
复制
library(dplyr)
library(tidyr)
library(purrr)
library(stringr)
out <- crossing(excel_files, imotion_files) %>%
            mutate(filename = str_remove(imotion_file, "_Imotions.txt"),
                    raw_data = map(imotion_files, extract_raw_data), 
                     event_data = map(imption_filess, extract_event_data),
                     paradigm_data = map(excel_files, ~ 
                           read_excel(.x, range = "H30:H328") %>%
                                        bind_cols(latency_ms, .))

根据OP的代码,只需在循环外部创建一次latency_ms,就可以在绑定列时使用它

票数 1
EN

Stack Overflow用户

发布于 2020-04-20 04:22:06

基于raw_data_first_timestamp的命名,我假设它是由extract_raw_data函数创建的-否则,您可以将latency_ms完全移出循环,就像akrun提到的那样。

如果您不想使用tidyverse,请参阅底部代码的修改版本。请注意,循环已被分解,以减少重复的操作。

使用循环时提高效率的一些一般提示:

  • 在尝试提高嵌套循环效率之前,请考虑是否可以拆分循环,以便存储来自早期循环的数据,以便在以后的循环中使用。这也可以通过嵌套循环和跟踪数据是否已经设置的变量来完成,但通常更简单的方法是中断循环,并在可能的情况下在循环之前取消对跟踪variables.
  • Create变量和调用函数的需要。根据语言和/或编译器的不同(如果使用了),在循环外创建变量可能无助于提高效率,但它仍然是很好的practice.
  • Variables,并且必须在循环内创建或调用的函数应该在尽可能高的作用域-或最外层的循环-中完成。

免责声明-我从未使用过R,因此可能存在语法错误。

代码语言:javascript
复制
excel_files <- list.files(pattern = ".xlsx"    , full.names = TRUE)
imotion_files <-list.files(pattern = 'Imotions.txt', full.names = TRUE)
paradigm_data_list <- vector("list", length(excel_files))

for (i in 1:length(excel_files)) {
  #read in paradigm data
  paradigm_data_list[[i]] <- read_excel(path = excel_files[[i]], range = "H30:H328")
}

for (imotion_file in imotion_files) {
  filename <- paste(sub("_Imotions.txt", "", imotion_file))
  raw_data <- extract_raw_data(imotion_file)
  event_data <- extract_event_data(imotion_file)

  #convert times to milliseconds
  latency_ms <- as.data.frame(
    sapply(
      df_col_only_ones$latency,
      convert_to_ms,
      raw_data_first_timestamp = raw_data_first_timestamp
    )
  )

  for (paradigm_data in paradigm_data_list) {
    merged <- bind_cols(latency_ms, paradigm_data)

    print(paste("writing = ", filename))
    write.table(
      merged,
      file = paste(filename, "_EVENT", ".txt", sep = ""),
      sep = '\t',
      col.names = TRUE,
      row.names = FALSE,
      quote = FALSE
    )
  }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61298109

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档