Saya sering memiliki file R Markdown utama atau file LaTeX knitr di mana saya memiliki source
beberapa file R lainnya (misalnya, untuk pemrosesan data). Namun, saya berpikir bahwa dalam beberapa kasus akan bermanfaat untuk memiliki file bersumber ini menjadi dokumen mereka sendiri yang dapat direproduksi (misalnya, file R Markdown yang tidak hanya menyertakan perintah untuk pemrosesan data tetapi juga menghasilkan dokumen yang dapat direproduksi yang menjelaskan keputusan pemrosesan data ).
Jadi, saya ingin memiliki perintah seperti source('myfile.rmd')
di file R Markdown utama saya. yang akan mengekstrak dan sumber semua kode R dalam potongan kode R dari myfile.rmd
. Tentu saja hal ini menimbulkan kesalahan.
Perintah berikut berfungsi:
```{r message=FALSE, results='hide'}
knit('myfile.rmd', tangle=TRUE)
source('myfile.R')
```
di mana results='hide'
dapat dihilangkan jika output diinginkan. Yaitu, knitr mengeluarkan kode R dari myfile.rmd
ke myfile.R
.
Namun, tampaknya tidak sempurna:
- itu menghasilkan pembuatan file tambahan
- ia harus muncul dalam potongan kodenya sendiri jika kontrol atas tampilan diperlukan.
- Tidak seanggun sesederhana itu
source(...)
.
Jadi pertanyaan saya: Apakah ada cara yang lebih elegan untuk mencari kode R dari file R Markdown?
Rmd
file. Tetapi Anda juga ingin membuat sumber dimarkdown
file lain menjadi file yang dirajut?include
dalam lateks. Jika penurunan harga mendukung penyertaan dokumen penurunan harga lainnya, seharusnya relatif mudah untuk membuat fungsi seperti itu.Jawaban:
Tampaknya Anda sedang mencari satu baris. Bagaimana kalau memasukkan ini ke dalam dirimu
.Rprofile
?ksource <- function(x, ...) { library(knitr) source(purl(x, output = tempfile()), ...) }
Namun, saya tidak mengerti mengapa Anda ingin
source()
kode di file Rmd itu sendiri. Maksud sayaknit()
akan menjalankan semua kode dalam dokumen ini, dan jika Anda mengekstrak kode dan menjalankannya dalam potongan, semua kode akan dijalankan dua kali saat Andaknit()
menjalankan dokumen ini (Anda menjalankan diri sendiri di dalam). Kedua tugas itu harus terpisah.Jika Anda benar-benar ingin menjalankan semua kode, RStudio telah membuat ini cukup mudah:
Ctrl + Shift + R
. Ini pada dasarnya memanggilpurl()
dan disource()
belakang layar.sumber
source()
atauknitr::knit()
menjalankan kode. Saya tahu orang-orang kurang paham dengan yang terakhir, tetapipurl()
tidak dapat diandalkan. Anda telah diperingatkan: github.com/yihui/knitr/pull/812#issuecomment-53088636caret
diperlukankernlab
dengan svm.Faktorkan kode umum ke dalam file R terpisah, lalu sumber file R tersebut ke dalam setiap file Rmd yang Anda inginkan.
jadi misalnya saya punya dua laporan yang harus saya buat, Wabah Flu dan Analisis Senjata vs Mentega. Secara alami saya akan membuat dua dokumen Rmd dan selesai dengannya.
Sekarang misalkan bos datang dan ingin melihat variasi harga Wabah Flu versus Mentega (mengendalikan amunisi 9mm).
Solusi saya adalah memfaktorkan proyek ke dalam file-file ini:
dalam setiap file Rmd saya akan memiliki sesuatu seperti:
Masalahnya di sini adalah kita kehilangan reproduktifitas. Solusi saya untuk itu adalah dengan membuat dokumen anak umum untuk disertakan ke dalam setiap file Rmd. Jadi di akhir setiap file Rmd yang saya buat, saya menambahkan ini:
Dan, tentu saja, autodoc.Rmd:
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>
NB, ini dirancang untuk alur kerja Rmd -> html. Ini akan menjadi kekacauan yang buruk jika Anda menggunakan lateks atau apa pun. Dokumen Rmd ini memeriksa lingkungan global untuk semua file source () dan menyertakan sumbernya di akhir dokumen Anda. Ini termasuk jquery ui, tablesorter, dan mengatur dokumen untuk menggunakan gaya akordeon untuk menampilkan / menyembunyikan file bersumber. Ini sedang dalam proses, tetapi jangan ragu untuk menyesuaikannya dengan penggunaan Anda sendiri.
Bukan satu kalimat, saya tahu. Semoga ini memberi Anda beberapa ide setidaknya :)
sumber
Mungkin orang harus mulai berpikir berbeda. Masalah saya adalah sebagai berikut: Tulis setiap kode yang biasanya Anda miliki dalam potongan .Rmd dalam file .R. Dan untuk dokumen Rmd yang Anda gunakan untuk merajut yaitu html, Anda hanya memiliki sisa
Dengan cara ini Anda mungkin akan membuat sekumpulan file .R dan Anda kehilangan keuntungan dari memproses semua kode "potongan demi potongan" menggunakan ctrl + alt + n (atau + c, tetapi biasanya ini tidak berhasil). Tapi, saya membaca buku tentang penelitian yang dapat direproduksi oleh Pak Gandrud dan menyadari, bahwa dia pasti menggunakan file knitr dan .Rmd hanya untuk membuat file html. Analisis Utama itu sendiri adalah file .R. Saya pikir dokumen .Rmd dengan cepat tumbuh terlalu besar jika Anda mulai melakukan seluruh analisis Anda di dalamnya.
sumber
Jika Anda hanya setelah kode, saya pikir sesuatu di sepanjang baris ini harus berfungsi:
readLines
grep
untuk menemukan potongan kode, mencari baris yang dimulai dengan<<<
misalnyawriteLines
Membungkus ini dalam suatu fungsi harus memberi Anda apa yang Anda butuhkan.
sumber
knit('myfile.rmd', tangle=TRUE)
dilakukannya di knitr. Saya rasa saya sedang mencari satu liner yang kusut dan bersumber dan idealnya tidak membuat file.textConnection
untuk meniru file, dan sumber dari itu. Ini akan menghindari pembuatan file.textConnection
mungkin tempat yang tepat untuk melihat.Peretasan berikut berfungsi dengan baik untuk saya:
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) }
sumber
Saya menggunakan fungsi kustom berikut
source_rmd <- function(rmd_file){ knitr::knit(rmd_file, output = tempfile()) } source_rmd("munge_script.Rmd")
sumber
Coba fungsi purl dari knitr:
source(knitr::purl("myfile.rmd", quiet=TRUE))
sumber
Saya akan merekomendasikan menyimpan analisis utama dan kode perhitungan dalam file .R dan mengimpor potongan sesuai kebutuhan dalam file .Rmd. Saya telah menjelaskan prosesnya di sini .
sumber
sys.source ("./ your_script_file_name.R", envir = knitr :: knit_global ())
letakkan perintah ini sebelum memanggil fungsi yang terdapat dalam nama_script_file_name.RAnda.
yang "./" menambahkan sebelum your_script_file_name.R untuk menunjukkan arah ke file Anda jika Anda sudah membuat sebuah Proyek.
Anda dapat melihat tautan ini untuk detail lebih lanjut: https://bookdown.org/yihui/rmarkdown-cookbook/source-script.html
sumber
ini berhasil untuk saya
source("myfile.r", echo = TRUE, keep.source = TRUE)
sumber
Saya menggunakan satu baris ini:
Lihat: File .Rmd saya menjadi sangat panjang. Apakah itu mungkin memisahkannya dan source () itu bagian yang lebih kecil dari main .Rmd?
sumber