У меня часто есть основной файл R Markdown или файл Knitr LaTeX, где source
есть другой файл R (например, для обработки данных). Однако я думал, что в некоторых случаях было бы полезно, чтобы эти исходные файлы были их собственными воспроизводимыми документами (например, файл R Markdown, который не только включает команды для обработки данных, но также создает воспроизводимый документ, который объясняет решения по обработке данных. ).
Таким образом, я хотел бы иметь команду, как source('myfile.rmd')
в моем основном файле R Markdown. который будет извлекать и исходить весь код R внутри фрагментов кода Rmyfile.rmd
. Конечно, это приводит к ошибке.
Следующая команда работает:
```{r message=FALSE, results='hide'}
knit('myfile.rmd', tangle=TRUE)
source('myfile.R')
```
где results='hide'
можно было бы опустить, если бы результат был желательным. Т.е. knitr выводит код R из myfile.rmd
в myfile.R
.
Однако это не кажется идеальным:
- это приводит к созданию дополнительного файла
- он должен отображаться в собственном фрагменте кода, если требуется управление отображением.
- Это не так элегантно, как просто
source(...)
.
Таким образом, мой вопрос: есть ли более элегантный способ получения кода R для файла R Markdown?
Rmd
файл другие сценарии R. Но вы также хотите, чтобы вmarkdown
связываемый файл исходили из других файлов?include
латекса. Если уценка поддерживает включение других документов уценки, создать такую функцию должно быть относительно легко.Ответы:
Похоже, вы ищете однострочный. Как насчет того, чтобы поместить это в свой
.Rprofile
?ksource <- function(x, ...) { library(knitr) source(purl(x, output = tempfile()), ...) }
Однако я не понимаю, зачем вам нужен
source()
код в самом файле Rmd. Я имею в виду, чтоknit()
будет запускать весь код в этом документе, и если вы извлечете код и запустите его фрагментом, весь код будет запущен дважды, когда выknit()
этот документ (вы запускаете себя внутри себя). Эти две задачи должны быть разделены.Если вы действительно хотите запустить весь код, RStudio сделал это довольно легко:
Ctrl + Shift + R
. Это в основном звонитpurl()
иsource()
за кадром.источник
source()
илиknitr::knit()
запуска кода. Я знаю, что люди менее знакомы с последним, ноpurl()
он ненадежен. Вы были предупреждены: github.com/yihui/knitr/pull/812#issuecomment-53088636caret
Требуется один случайkernlab
с svm.Разложите общий код на отдельный R-файл, а затем отправьте этот R-файл в каждый Rmd-файл, который вы хотите использовать.
так, например, предположим, что у меня есть два отчета, которые мне нужно сделать: «Вспышки гриппа» и «Анализ пистолетов и масла». Естественно, я бы создал два документа Rmd и покончил с этим.
Теперь предположим, что приходит босс и хочет увидеть разницу в цене между вспышками гриппа и маслом (с учетом 9-мм патронов).
Мое решение заключалось в том, чтобы разложить проект на эти файлы:
в каждом файле Rmd у меня будет что-то вроде:
Проблема здесь в том, что мы теряем воспроизводимость. Мое решение - создать общий дочерний документ для включения в каждый файл Rmd. Поэтому в конце каждого создаваемого мной Rmd-файла я добавляю следующее:
И, конечно же, 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, это разработано для рабочего процесса Rmd -> html. Это будет ужасный беспорядок, если вы выберете латекс или что-нибудь еще. Этот документ Rmd просматривает глобальную среду для всех файлов ed source () и включает их источник в конец вашего документа. Он включает jquery ui, tablesorter и настраивает документ для использования стиля аккордеона для отображения / скрытия исходных файлов. Работа над ним еще не завершена, но вы можете адаптировать ее для своих нужд.
Я знаю, что не однострочник. Надеюсь, это даст вам хоть какие-то идеи :)
источник
Наверное, надо думать иначе. Моя проблема заключается в следующем: напишите каждый код, который у вас обычно был бы в блоке .Rmd в файле .R. А для документа Rmd, который вы используете для вязания, то есть html, у вас осталось только
Таким образом вы, вероятно, создадите кучу файлов .R и потеряете преимущество обработки всего кода «кусок за фрагментом» с помощью ctrl + alt + n (или + c, но обычно это не работает). Но я прочитал книгу г-на Гандруда о воспроизводимых исследованиях и понял, что он определенно использует файлы knitr и .Rmd исключительно для создания файлов html. Сам основной анализ - это файл .R. Я думаю, что .Rmd-документы быстро станут слишком большими, если вы начнете анализировать их внутри.
источник
Если вы сразу после кода, я думаю, что что-то в этом роде должно сработать:
readLines
grep
для поиска фрагментов кода, ища строки, начинающиеся,<<<
например, сwriteLines
Обертывание этого в функции должно дать вам то, что вам нужно.
источник
knit('myfile.rmd', tangle=TRUE)
делает в knitr. Думаю, я ищу один лайнер, который запутывает и исходный текст, и в идеале не создает никаких файлов.textConnection
для имитации файла и использовать его как источник. Это позволит избежать создания файла.textConnection
может быть местом, где стоит посмотреть.У меня отлично сработал следующий хак:
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) }
источник
Я использую следующую пользовательскую функцию
source_rmd <- function(rmd_file){ knitr::knit(rmd_file, output = tempfile()) } source_rmd("munge_script.Rmd")
источник
Попробуйте функцию изнаночной вязки:
source(knitr::purl("myfile.rmd", quiet=TRUE))
источник
Я бы рекомендовал хранить основной код анализа и расчета в файле .R и при необходимости импортировать фрагменты в файл .Rmd. Я объяснил процесс здесь .
источник
sys.source ("./ ваш_скрипт_имя_файла.R", envir = knitr :: knit_global ())
поместите эту команду перед вызовом функций, содержащихся в your_script_file_name.R.
добавление "./" перед your_script_file_name.R, чтобы показать направление к вашему файлу, если вы уже создали проект.
Вы можете увидеть эту ссылку для более подробной информации: https://bookdown.org/yihui/rmarkdown-cookbook/source-script.html
источник
это сработало для меня
source("myfile.r", echo = TRUE, keep.source = TRUE)
источник
Я использую этот однострочный:
См .: Мой файл .Rmd становится очень длинным. Возможно ли разделить его и source () на меньшие части из основного .Rmd?
источник