आर: विशाल(> 20 जीबी) फ़ाइलों के xmlEventParse के दौरान मेमोरी प्रबंधन



memory-management xml-parsing (1)

यहां एक उदाहरण है, हमारे पास एक लांच स्क्रिप्ट invoke.sh , जो एक आर स्क्रिप्ट कॉल करता है और यूआरएल और फ़ाइल नाम पैरामीटर के रूप में देता है ... इस मामले में, मैंने पहले टेस्ट फाइल medsamp2015.xml डाउनलोड की थी ./data निर्देशिका

  • मेरी समझ में invoke.sh स्क्रिप्ट में एक लूप बनाने और लक्ष्य फ़ाइल नामों की सूची के माध्यम से पुनरावृत्त होना होगा। प्रत्येक फ़ाइल के लिए आप एक आर आवृत्ति का आह्वान करते हैं, इसे डाउनलोड करें, फ़ाइल संसाधित करें और आगे बढ़ें

चेतावनी: मैंने किसी भी अन्य डाउनलोड फ़ाइलों और प्रारूपों के विरुद्ध आपके फ़ंक्शन को नहीं देखा या परिवर्तित नहीं किया। मैं लाइन (प्रिंट) () आवरण को लाइन 62 पर निकालकर आउटपुट का मुद्रण बंद कर दूँगा।

print( cbind(c(rep(v1, length(v2))), v2))
  • देखें: प्रिंट आउट के लिए runtime.txt
  • आउटपुट .csv फ़ाइलें। / ./data निर्देशिका में रखी गई हैं।

नोट: यह इस विषय पर मेरे द्वारा दिए गए पिछले उत्तर का एक व्युत्पन्न है: Windows में रिलीज़ नहीं की गई स्मृति मुझे आशा है कि यह उदाहरण के माध्यम से मदद करता है।

लॉन्च स्क्रिप्ट

  1 #!/usr/local/bin/bash -x
  2
  3 R --no-save -q --slave < ./47162861.R --args "https://www.nlm.nih.gov/databases/dtd" "medsamp2015.xml"

आर फ़ाइल - 47162861.R आर

# Set working directory

projectDir <- "~/dev/stackoverflow/47162861"
setwd(projectDir)

# -----------------------------------------------------------------------------
# Load required Packages...
requiredPackages <- c("XML")

ipak <- function(pkg) {
  new.pkg <- pkg[!(pkg %in% installed.packages()[, "Package"])]
  if (length(new.pkg))
    install.packages(new.pkg, dependencies = TRUE)
  sapply(pkg, require, character.only = TRUE)
}

ipak(requiredPackages)

# -----------------------------------------------------------------------------
# Load required Files
# trailingOnly=TRUE means that only your arguments are returned
args <- commandArgs(trailingOnly = TRUE)

if ( length(args) != 0 ) {
  dataDir <- file.path(projectDir,"data")
  fileUrl = args[1]
  fileName = args[2]
} else {
  dataDir <- file.path(projectDir,"data")
  fileUrl <- "https://www.nlm.nih.gov/databases/dtd"
  fileName <- "medsamp2015.xml"
}

# -----------------------------------------------------------------------------
# Download file

# Does the directory Exist? If it does'nt create it
if (!file.exists(dataDir)) {
  dir.create(dataDir)
}

# Now we check if we have downloaded the data already if not we download it

if (!file.exists(file.path(dataDir, fileName))) {
  download.file(fileUrl, file.path(dataDir, fileName), method = "wget")
}

# -----------------------------------------------------------------------------
# Now we extrat the data

tempdat <- data.frame(pmid = as.numeric(), lname = character(),
  stringsAsFactors = FALSE)
cnt <- 1

branchFunction <- function() {
  func <- function(x, ...) {
    v1 <- xpathSApply(x, path = "//PMID", xmlValue)
    v2 <- xpathSApply(x, path = "//Author/LastName", xmlValue)
    print(cbind(c(rep(v1, length(v2))), v2))

    # below is where I store/write the temp data along the way
    # but even without doing this, memory is used (even after
    # clearing)

    tempdat <<- rbind(tempdat, cbind(c(rep(v1, length(v2))),
      v2))
    if (nrow(tempdat) > 1000) {
      outname <- file.path(dataDir, paste0(cnt, ".csv")) # Create FileName
      write.csv(tempdat, outname, row.names = F) # Write File to created directory
      tempdat <<- data.frame(pmid = as.numeric(), lname = character(),
        stringsAsFactors = FALSE)
      cnt <<- cnt + 1
    }
  }
  list(MedlineCitation = func)
}

myfunctions <- branchFunction()

# -----------------------------------------------------------------------------
# RUN
xmlEventParse(file = file.path(dataDir, fileName),
              handlers = NULL,
              branches = myfunctions)

टेस्ट फ़ाइल और आउटपुट

~ / dev / stackoverflow / 47162861 / डेटा / medsamp2015.xml

$ ll                                                            
total 2128
drwxr-xr-[email protected] 7 hidden  staff   238B Nov 10 11:05 .
drwxr-xr-[email protected] 9 hidden  staff   306B Nov 10 11:11 ..
-rw-r--r[email protected] 1 hidden  staff    32K Nov 10 11:12 1.csv
-rw-r--r[email protected] 1 hidden  staff    20K Nov 10 11:12 2.csv
-rw-r--r[email protected] 1 hidden  staff    23K Nov 10 11:12 3.csv
-rw-r--r[email protected] 1 hidden  staff    37K Nov 10 11:12 4.csv
-rw-r--r[email protected] 1 hidden  staff   942K Nov 10 11:05 medsamp2015.xml

रनटाइम आउटपुट

> ./invoke.sh > runtime.txt
+ R --no-save -q --slave --args https://www.nlm.nih.gov/databases/dtd medsamp2015.xml
Loading required package: XML

फ़ाइल: रनटाइम। Txt

इस पिछले प्रश्न पर बिल्डिंग ( यहां देखें ), मैं नोड-अलग डेटा को सहेजते समय xmlEventParse के माध्यम से कई, बड़ी XML फ़ाइलों में पढ़ने का प्रयास कर रहा हूं। इस नमूना xml के साथ कार्य करना: https://www.nlm.nih.gov/databases/dtd/medsamp2015.xml

नीचे दिए गए कोड xpathSapply को आवश्यक मानों को निकालने के लिए और यदि बयान उन मानों को एक साथ जोड़ते हैं जो अद्वितीय मान (पीएमआईडी) से मेल खाते हैं, तो प्रत्येक रिकॉर्ड के भीतर गैर-अद्वितीय मानों (अंतिम नाम) में - जो इसके लिए हो सकता है नहीं LastNames होना लक्ष्य का इस्तेमाल किया जाने वाली स्मृति की मात्रा को कम करने के लिए रास्ते में छोटे सीएसवी की एक श्रृंखला (यहां, हर 1000 अंतिम नाम के बाद) लिखना है।

जब पूर्ण आकार के डेटा सेट पर चलाया जाता है, तो कोड सफलतापूर्वक बैचों में फाइलों को आउटपुट करता है, हालांकि अभी भी कुछ स्मृति को संग्रहीत किया जा रहा है जो सभी रैम का उपयोग करने के बाद अंततः सिस्टम त्रुटि का कारण बनता है। कोड चलाते समय मैंने कार्य प्रबंधक देख लिया है और कार्यक्रम की प्रगति के रूप में आर की स्मृति बढ़ती है। और अगर मैं कार्यक्रम को मध्य रन में रोकता हूं और फिर आर वर्कस्पेस को छिपे हुए आइटमों सहित साफ़ कर देता हूं, तो मेमोरी अभी भी आर के उपयोग में प्रतीत होता है। जब तक मैं बंद नहीं करता तब तक आर यादृप्ति को मुक्त नहीं किया जाता है।

यह अपने आप को कई बार चलाएं और आप देखेंगे कि आर के मेमोरी का उपयोग कार्यक्षेत्र को साफ़ करने के बाद भी बढ़ेगा।

कृपया सहायता कीजिए! यह समस्या बड़ी एक्सएमएल फाइलों में इस तरीके से पढ़ने वाले अन्य लोगों के लिए सामान्य प्रतीत होती है ( इस प्रश्न में उदाहरण के लिए टिप्पणियां देखें)।

मेरा कोड निम्नानुसार है:

library(XML)

filename <- "~/Desktop/medsamp2015.xml"

tempdat <- data.frame(pmid=as.numeric(),
                      lname=character(), 
                      stringsAsFactors=FALSE) 
cnt <- 1
branchFunction <- function() {
  func <- function(x, ...) {
    v1 <- xpathSApply(x, path = "//PMID", xmlValue)
    v2 <- xpathSApply(x, path = "//Author/LastName", xmlValue)
    print(cbind(c(rep(v1,length(v2))), v2))

    #below is where I store/write the temp data along the way
    #but even without doing this, memory is used (even after clearing)

    tempdat <<- rbind(tempdat,cbind(c(rep(v1,length(v2))), v2))
    if (nrow(tempdat) > 1000){
      outname <- paste0("~/Desktop/outfiles",cnt,".csv")
      write.csv(tempdat, outname , row.names = F)
      tempdat <<- data.frame(pmid=as.numeric(),
                            lname=character(), 
                            stringsAsFactors=FALSE)
      cnt <<- cnt+1
    }
  }
  list(MedlineCitation = func)
}

myfunctions <- branchFunction()

#RUN
xmlEventParse(
  file = filename, 
  handlers = NULL, 
  branches = myfunctions
)




large-files