为什么我的 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
,没有问题。
我写了一个简单的脚本,它从我的文件夹中打开每个 .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
,没有问题。