आर मार्केड फाइल को कैसे सोर्स करें जैसे `सोर्स ('myfile.r')`?


89

मेरे पास अक्सर एक मुख्य आर मार्कडाउन फ़ाइल या निट्रा लाटेक्स फ़ाइल होती है जहां मैं sourceकुछ अन्य आर फ़ाइल (जैसे, डेटा प्रोसेसिंग के लिए)। हालाँकि, मैं सोच रहा था कि कुछ उदाहरणों में यह फायदेमंद होगा कि इन खट्टी फाइलों के अपने स्वयं के प्रतिलिपि प्रस्तुत करने योग्य दस्तावेज हों (उदाहरण के लिए, एक आर मार्केडाउन फाइल जिसमें न केवल डेटा प्रोसेसिंग के लिए कमांड शामिल हैं, बल्कि एक प्रतिलिपि प्रस्तुत करने योग्य दस्तावेज भी है जो डेटा प्रोसेसिंग निर्णयों को स्पष्ट करता है। )।

इस प्रकार, मैं source('myfile.rmd')अपने मुख्य आर मार्केडाउन फ़ाइल की तरह एक कमांड रखना चाहूंगा । कि आर कोड के अंदर सभी आर कोड निकालने और स्रोत होगा myfile.rmd। बेशक, यह एक त्रुटि को जन्म देता है।

निम्न आदेश काम करता है:

```{r message=FALSE, results='hide'}
knit('myfile.rmd', tangle=TRUE)
source('myfile.R')
```

results='hide'अगर आउटपुट वांछित था, तो कहां छोड़ा जा सकता है। यानी, knitr से आर कोड आउटपुट myfile.rmdमें myfile.R

हालांकि, यह सही नहीं लगता है:

  • यह एक अतिरिक्त फ़ाइल के निर्माण में परिणाम है
  • यदि इसके प्रदर्शन पर नियंत्रण आवश्यक है तो इसे अपने कोड चंक में दिखाई देना चाहिए।
  • यह उतना सरल नहीं है source(...)

इस प्रकार मेरा प्रश्न: क्या आर मार्कडाउन फाइल के आर कोड को सोर्स करने का एक और अधिक सुरुचिपूर्ण तरीका है?


मुझे वास्तव में आपके प्रश्न को समझने में बहुत कठिन समय लग रहा है (मैंने इसे कई बार पढ़ा)। आप आसानी से एक Rmdफ़ाइल में अन्य आर स्क्रिप्ट को स्रोत कर सकते हैं । लेकिन आप भी अन्य markdownफाइलों में एक फाइल को बुना हुआ होना चाहते हैं?
मयासुर

4
मैं आर कोड के अंदर R कोड को आर मार्कडाउन फ़ाइलों (यानी, .rmd) में आर कोड करना चाहता हूं? मैंने चीजों को स्पष्ट करने की कोशिश करने के लिए प्रश्न को थोड़ा संपादित किया है।
जेरोमे एंग्लीम

includeलेटेक्स की तर्ज पर कुछ । यदि मार्कडाउन अन्य मार्कडाउन दस्तावेजों को शामिल करने का समर्थन करता है, तो इस तरह के फ़ंक्शन को बनाना आसान होना चाहिए।
पॉल हीमस्ट्रा

@PaulHiemstra मुझे लगता है कि पाठ और आर कोड विखंडू को स्रोत करने की क्षमता भी उपयोगी होगी। मैं विशेष रूप से आर मार्केड डॉक्यूमेंट में सिर्फ कोड सोर्स करने के बारे में सोच रहा हूं।
जेरोमे एंग्लीम

जवाबों:


35

ऐसा लगता है कि आप एक-लाइनर की तलाश कर रहे हैं। कैसे इस बारे में अपने में डाल .Rprofile?

ksource <- function(x, ...) {
  library(knitr)
  source(purl(x, output = tempfile()), ...)
}

हालाँकि, मुझे यह समझ नहीं आ रहा है कि आप source()Rmd फाइल में ही कोड क्यों चाहते हैं । मेरा मतलब है कि knit()इस दस्तावेज़ में सभी कोड चलेंगे, और यदि आप कोड को निकालते हैं और इसे एक चंक में चलाते हैं, तो यह कोड आपके द्वारा knit()इस दस्तावेज़ को चलाने पर दो बार चलाया जाएगा (आप खुद को अपने अंदर चलाते हैं)। दोनों कार्य अलग-अलग होने चाहिए।

यदि आप वास्तव में सभी कोड चलाना चाहते हैं, तो RStudio ने इसे काफी आसान बना दिया है Ctrl + Shift + R:। यह मूल रूप से कॉल purl()और source()दृश्य के पीछे है।


8
हाय @ यिहुई मुझे लगता है कि यह उपयोगी है क्योंकि कभी-कभी आपका विश्लेषण छोटी लिपियों में आयोजित किया जा सकता है, लेकिन आपकी रिपोर्ट में आप पूरी पाइपलाइन के लिए कोड चाहते हैं।
ल्यूसजेरोन

9
तो यहाँ उपयोग का मामला यह है कि आप सभी कोड लिखना चाहते हैं और इसे बहुत अधिक प्रलेखित और समझाया जाना चाहिए, लेकिन कोड किसी अन्य स्क्रिप्ट द्वारा चलाया जाता है।
ब्राश इक्विलिब्रियम

4
@BrashEquilibrium यह कोड का उपयोग करने source()या knitr::knit()चलाने का मामला है । मुझे पता है कि लोग बाद वाले से कम परिचित हैं, लेकिन purl()विश्वसनीय नहीं हैं। आपको चेतावनी दी गई है: github.com/yihui/knitr/pull/812#issuecomment-53088636
Yihui Xie

5
@ यिहुई आपके विचार में 'स्रोत (purl (x, ...))' का प्रस्तावित विकल्प क्या होगा? डुप्लिकेट चंक लेबलों के बारे में एक त्रुटि के बिना एक स्रोत एकाधिक * .Rmd-Files को कैसे चला सकता है? मैं इसके बदले में दस्तावेज़ को वापस जाना चाहता हूँ और इसे बुनना चाहता हूँ। मैं कई फ़ाइलों के लिए * .Rd का उपयोग करता हूं, जो कि मुझे संभावित रूप से दूसरों के साथ निर्यात करना और चर्चा करना है, इसलिए विश्लेषण के सभी चरणों के लिए मल्टीपल Rmd-Files को सक्षम करना बहुत अच्छा होगा।
आंकड़े- hb

knitr त्रुटि "त्रुटि: आवश्यक पैकेज गायब है" का उत्सर्जन करता है, जब यह .rmd फ़ाइल प्रदान करता है। मुझे असली त्रुटि संदेश को खोजने के लिए .rmd फ़ाइल में कोड निष्पादित करना होगा जिसमें लापता पैकेज का नाम है। Svm के साथ एक मामला caretआवश्यक है kernlab
सीडब्ल्यू

19

एक अलग R फ़ाइल में सामान्य कोड को फैक्टर करें, और फिर उस Rm फ़ाइल को उस फ़ाइल में स्रोत करें जिसे आप चाहते हैं।

इसलिए उदाहरण के लिए मान लें कि मेरे पास दो रिपोर्ट हैं जिन्हें मुझे बनाने की आवश्यकता है, फ्लू का प्रकोप और बंदूकें बनाम मक्खन विश्लेषण। स्वाभाविक रूप से मैं दो Rmd दस्तावेज़ बनाऊँगा और उसके साथ काम करूँगा।

अब मान लीजिए बॉस साथ आता है और फ्लू के प्रकोपों ​​बनाम मक्खन की कीमतों (9 मिमी बारूद के लिए नियंत्रण) की विविधताओं को देखना चाहता है।

  • नई रिपोर्ट में रिपोर्ट का विश्लेषण करने के लिए कोड को कॉपी और पेस्ट करना कोड के पुन: उपयोग के लिए एक बुरा विचार है, आदि।
  • मैं चाहता हूं कि यह अच्छा लगे।

मेरा समाधान परियोजना को इन फाइलों में शामिल करना था:

  • Flu.Rmd
    • flu_data_import.R
  • Guns_N_Butter.Rmd
    • guns_data_import.R
    • butter_data_import.R

प्रत्येक Rmd फ़ाइल के भीतर मुझे कुछ ऐसा चाहिए:

```{r include=FALSE}
source('flu_data_import.R')
```

यहाँ समस्या यह है कि हम प्रजनन क्षमता खो देते हैं। मेरा समाधान यह है कि प्रत्येक Rmd फ़ाइल में शामिल करने के लिए एक सामान्य चाइल्ड डॉक्यूमेंट बनाया जाए। इसलिए मेरे द्वारा बनाई गई प्रत्येक Rmd फ़ाइल के अंत में, मैं इसे जोड़ता हूं:

```{r autodoc, child='autodoc.Rmd', eval=TRUE}
``` 

और, ज़ाहिर है, ऑटोडोक.मॉड:

Source Data & Code
----------------------------
<div id="accordion-start"></div>

```{r sourcedata, echo=FALSE, results='asis', warnings=FALSE}

if(!exists(autodoc.skip.df)) {
  autodoc.skip.df <- list()
}

#Generate the following table:
for (i in ls(.GlobalEnv)) {
  if(!i %in% autodoc.skip.df) {
    itm <- tryCatch(get(i), error=function(e) NA )
    if(typeof(itm)=="list") {
      if(is.data.frame(itm)) {
        cat(sprintf("### %s\n", i))
        print(xtable(itm), type="html", include.rownames=FALSE, html.table.attributes=sprintf("class='exportable' id='%s'", i))
      }
    }
  }
}
```
### Source Code
```{r allsource, echo=FALSE, results='asis', warning=FALSE, cache=FALSE}
fns <- unique(c(compact(llply(.data=llply(.data=ls(all.names=TRUE), .fun=function(x) {a<-get(x); c(normalizePath(getSrcDirectory(a)),getSrcFilename(a))}), .fun=function(x) { if(length(x)>0) { x } } )), llply(names(sourced), function(x) c(normalizePath(dirname(x)), basename(x)))))

for (itm in fns) {
  cat(sprintf("#### %s\n", itm[2]))
  cat("\n```{r eval=FALSE}\n")
  cat(paste(tryCatch(readLines(file.path(itm[1], itm[2])), error=function(e) sprintf("Could not read source file named %s", file.path(itm[1], itm[2]))), sep="\n", collapse="\n"))
  cat("\n```\n")
}
```
<div id="accordion-stop"></div>
<script type="text/javascript">
```{r jqueryinclude, echo=FALSE, results='asis', warning=FALSE}
cat(readLines(url("http://code.jquery.com/jquery-1.9.1.min.js")), sep="\n")
```
</script>
<script type="text/javascript">
```{r tablesorterinclude, echo=FALSE, results='asis', warning=FALSE}
cat(readLines(url("http://tablesorter.com/__jquery.tablesorter.js")), sep="\n")
```
</script>
<script type="text/javascript">
```{r jqueryuiinclude, echo=FALSE, results='asis', warning=FALSE}
cat(readLines(url("http://code.jquery.com/ui/1.10.2/jquery-ui.min.js")), sep="\n")
```
</script>
<script type="text/javascript">
```{r table2csvinclude, echo=FALSE, results='asis', warning=FALSE}
cat(readLines(file.path(jspath, "table2csv.js")), sep="\n")
```
</script>
<script type="text/javascript">
  $(document).ready(function() {
  $('tr').has('th').wrap('<thead></thead>');
  $('table').each(function() { $('thead', this).prependTo(this); } );
  $('table').addClass('tablesorter');$('table').tablesorter();});
  //need to put this before the accordion stuff because the panels being hidden makes table2csv return null data
  $('table.exportable').each(function() {$(this).after('<a download="' + $(this).attr('id') + '.csv" href="data:application/csv;charset=utf-8,'+encodeURIComponent($(this).table2CSV({delivery:'value'}))+'">Download '+$(this).attr('id')+'</a>')});
  $('#accordion-start').nextUntil('#accordion-stop').wrapAll("<div id='accordion'></div>");
  $('#accordion > h3').each(function() { $(this).nextUntil('h3').wrapAll("<div>"); });
  $( '#accordion' ).accordion({ heightStyle: "content", collapsible: true, active: false });
</script>

नायब, यह Rmd -> html वर्कफ़्लो के लिए डिज़ाइन किया गया है। यदि आप लेटेक्स या किसी अन्य चीज़ के साथ जाते हैं तो यह एक बदसूरत गड़बड़ होगी। यह Rmd दस्तावेज़ सभी स्रोत () एड फ़ाइलों के लिए वैश्विक वातावरण के माध्यम से दिखता है और आपके दस्तावेज़ के अंत में उनके स्रोत को शामिल करता है। इसमें jquery ui, तालिकाओं को शामिल किया गया है, और दस्तावेज़ को सेट की गई फ़ाइलों को दिखाने / छिपाने के लिए एक अकॉर्डियन शैली का उपयोग करने के लिए सेट किया गया है। यह प्रगति पर काम है, लेकिन इसे अपने स्वयं के उपयोग के लिए स्वतंत्र महसूस करें।

एक-लाइनर नहीं, मुझे पता है। आशा है कि यह आपको कम से कम कुछ विचार देता है :)


4

शायद किसी को अलग सोचना शुरू करना चाहिए। मेरा मुद्दा निम्नलिखित है: प्रत्येक कोड को आप सामान्य रूप से लिख सकते हैं। और Rmd डॉक्यूमेंट के लिए आप एक html का उपयोग करते हैं, आपके पास केवल शेष होता है

```{R Chunkname, Chunkoptions}  
source(file.R)  
```

इस तरह आप शायद .R फ़ाइलों का एक समूह बना लेंगे और आप ctrl + alt + n (या + c) का उपयोग करके "chunk के बाद सभी कोड" को संसाधित करने का लाभ खो देंगे, लेकिन आम तौर पर यह काम नहीं करता है)। लेकिन, मैंने श्री गांदरुद द्वारा पुनरुत्पादक शोध के बारे में पुस्तक पढ़ी और महसूस किया, कि वह निश्चित रूप से html फाइलें बनाने के लिए निट और .Rmd फ़ाइलों का उपयोग करता है। मुख्य विश्लेषण अपने आप में एक .R फाइल है। मुझे लगता है। यदि आप अपना पूरा विश्लेषण अंदर ही करने लगें तो। Rmd दस्तावेज़ बहुत तेज़ी से बढ़ते हैं।


3

यदि आप कोड के बाद बस मुझे लगता है कि इन लाइनों के साथ कुछ काम करना चाहिए:

  1. मार्कडाउन / आर फ़ाइल को पढ़ें readLines
  2. उदाहरण के लिए grepशुरू होने वाली लाइनों की खोज करने के लिए कोड विखंडू का उपयोग करें<<<
  3. उस ऑब्जेक्ट का सबसेट लें जिसमें केवल कोड प्राप्त करने के लिए मूल लाइनें हों
  4. इसका उपयोग करके एक अस्थायी फ़ाइल में डंप करें writeLines
  5. अपने आर सत्र में इस फ़ाइल को स्रोत

एक समारोह में इसे लपेटकर आपको वह देना चाहिए जो आपको चाहिए।


1
धन्यवाद, मुझे लगता है कि काम करेगा। हालांकि, पहले चार बिंदुओं की आवाज़ ऐसी है जैसे कि स्टंगल पहले से ही स्वेव के लिए विश्वसनीय तरीके से knit('myfile.rmd', tangle=TRUE)करता है और नाइट्र में क्या करता है। मुझे लगता है कि मैं एक लाइनर की तलाश कर रहा हूं जो दोनों tangles और स्रोतों और आदर्श रूप से कोई फ़ाइल नहीं बनाता है।
जेरोमे एंग्लीम

एक बार जब आप इसे किसी फ़ंक्शन में लपेटते हैं तो यह एक ऑनलाइनर बन जाता है;)। आप जो कुछ भी कर सकते हैं वह textConnectionकिसी फ़ाइल की नकल करने और उस से स्रोत का उपयोग करने के लिए है। इससे कोई फ़ाइल बनाई जा रही है।
पॉल हीमस्ट्रा

हाँ। textConnectionदेखने के लिए जगह हो सकती है।
जेरोमे एंग्लीम

2

निम्नलिखित हैक ने मेरे लिए ठीक काम किया:

library(readr)
library(stringr)
source_rmd <- function(file_path) {
  stopifnot(is.character(file_path) && length(file_path) == 1)
  .tmpfile <- tempfile(fileext = ".R")
  .con <- file(.tmpfile) 
  on.exit(close(.con))
  full_rmd <- read_file(file_path)
  codes <- str_match_all(string = full_rmd, pattern = "```(?s)\\{r[^{}]*\\}\\s*\\n(.*?)```")
  stopifnot(length(codes) == 1 && ncol(codes[[1]]) == 2)
  codes <- paste(codes[[1]][, 2], collapse = "\n")
  writeLines(codes, .con)
  flush(.con)
  cat(sprintf("R code extracted to tempfile: %s\nSourcing tempfile...", .tmpfile))
  source(.tmpfile)
}

2

मैं निम्नलिखित कस्टम फ़ंक्शन का उपयोग करता हूं

source_rmd <- function(rmd_file){
  knitr::knit(rmd_file, output = tempfile())
}

source_rmd("munge_script.Rmd")


1

मैं मुख्य विश्लेषण और गणना कोड को .R फ़ाइल में रखने और आवश्यकता के अनुसार विखंडू को आयात करने की सलाह दूंगा। Rmd फ़ाइल। मैंने यहाँ प्रक्रिया को समझाया है


1

sys.source ("./ your_script_file_name.R", envir = knitr :: knit_global ())

इस कमांड को अपने_सस्क्रिप्ट_फाइल_नाम। आर में निहित फ़ंक्शन को कॉल करने से पहले रखें।

यदि आपने पहले ही प्रोजेक्ट बनाया है, तो अपनी फ़ाइल को दिशा दिखाने के लिए your_script_file_name.R से पहले जोड़ना "।"

आप इस लिंक को और अधिक विवरण के लिए देख सकते हैं: https://bookdown.org/yihui/rmarkdown-cookbook/source-s.html


0

यह मेरे लिए काम किया

source("myfile.r", echo = TRUE, keep.source = TRUE)

0
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.