为什么我的 R 脚本占用了计算机的所有内存?

Why is my R script using all the computer's memory?

我写了一个简单的脚本,它从我的文件夹中打开每个 .docx 文档并查找特定的单词。如果存在任何单词,它会提取一个 ID 号,然后转到下一个文档。问题是在约 1500 个文档之后,它会消耗所有计算机内存,R 会卡住并中止。我不知道为什么会这样——我的脚本不应该使用那么多内存。如有任何建议,我们将不胜感激!

rm(list=ls()) #clean environment
library(qdapTools)
setwd("C:/DocxArchive/ParentFolder")
results <- 0 #store results here
years_list <- c("2010","2011","2012","2013","2014","2015","2016","2017","2018","2019","2020")

for (year_index in 1:11) {
  parent_dir <- years_list[year_index]     
  file_list <- list.files(path = parent_dir, recursive = TRUE) #get list of file names
  items_to_delete <- grep('~',file_list) #find temporary files - name begins with '~'
  file_list <- file_list[-items_to_delete] #delete temporary files from file list
  length_of_file_list <- length(file_list)
  file_num <- 1 #initialize file number index
  while(file_num <= length_of_file_list){ 
    DOCX <- read_docx(file=file.path(parent_dir, file_list[file_num]))
      index_of_HITEC1 <- grepl("HI TEC", DOCX, fixed=FALSE, ignore.case=TRUE) 
      index_of_HITEC2 <- grepl("HITEC", DOCX, fixed=FALSE, ignore.case=TRUE) 
      index_of_HITEC3 <- grepl("HI-TEC", DOCX, fixed=FALSE, ignore.case=TRUE) 
      HITEC1_num <- which.max(index_of_HITEC1) #line in document where word exists
      HITEC2_num <- which.max(index_of_HITEC2) #line in document where word exists
      HITEC3_num <- which.max(index_of_HITEC3) #line in document where word exists
      HITEC_sum <- HITEC1_num+HITEC2_num+HITEC3_num
      if (HITEC_sum > 3){
        index_of_person_ID <- grepl("ID:", DOCX, fixed=TRUE) #find lines where ID exist
        text <- DOCX[index_of_person_ID==TRUE] #keep only lines where ID exist
        text <- gsub("[^0-9]","",text) #delete everything except numbers
        results <- c(results,text)
      } #end of if loop
      file_num <- file_num+1
   } #end of while loop 
} #end of for loop

We made our way into the second Circle, here live the gluttons.

读一点 R inferno 可能会对您有所帮助。除了 read_docx 可能引起的内存泄漏外,我认为有问题的行是:

results <- c(results, text)

R Inferno Ch 中有一些细节。 2,但基本上当你这样做时,你会得到一份 results 从它在内存中的旧位置到新位置的完整副本,并且这种情况发生在每次循环迭代中。这意味着大多数时候您将使用几乎两倍的内存,甚至可能更多,因为 R 的垃圾收集器通常只在请求时释放内存。

您可以通过使用不同的编程模式来保存结果来改进此代码,或者,如果您觉得很懒惰,可以定期调用 gc()(例如,每循环的第 10 次迭代)。

更新:内存泄漏是qdapTools::read_docx的错。使用officer::read_docx,没有问题。