YAML текущая дата в rmarkdown

247

Мне интересно, есть ли хитрость, чтобы поместить текущую дату во внешнюю оболочку YAML .rmdдокумента для обработки knitrи rmarkdownпакета. Я имел обыкновение иметь следующую строку в верхней части моих вики-страниц,

   _baptiste, `r format(Sys.time(), "%d %B, %Y")`_

и он будет преобразован в крещение, 3 мая 2014 года в выводе html. Теперь я хотел бы воспользоваться расширенной оболочкой pandoc, предоставляемой rmarkdown, но наличие r-кода в заголовке YAML, похоже, не работает:

---
title: "Sample Document"
output:
  html_document:
    toc: true
    theme: united
date: `r format(Sys.time(), "%d %B, %Y")`
author: baptiste
---

Error in yaml::yaml.load(front_matter) : 
  Scanner error: while scanning for the next token at line 6, column 7
 found character that cannot start any token at line 6, column 7
Calls: <Anonymous> ... output_format_from_yaml_front_matter -> 
       parse_yaml_front_matter -> <Anonymous> -> .Call

Любое решение?

Батист
источник
7
Я удивлен, что это больше не работает, так как это именно то, что я делал раньше. Я посмотрю, что происходит в последнее время. Кстати, yaml также поддерживает значения, вычисленные по R !expr, например date: !expr Sys.time(), но теперь это тоже не работает.
Йихуэй Се

Ответы:

366

Это немного сложно, но вам просто нужно сделать dateполе действительным в YAML, заключив в кавычки выражение R, например:

date: "`r format(Sys.time(), '%d %B, %Y')`"

Тогда ошибка синтаксического анализа исчезнет, ​​и в выходных данных уценки будет сгенерирована дата, чтобы Pandoc мог использовать значение из Sys.time().

Йихуэй Се
источник
Я предполагаю, что это означает, что встроенный R не может использоваться, например, для списка, includes: after_body: [ ... ]поскольку действительный YAML будет только строкой имени файла ... Так что нет возможности includes: "`r list.files(...)`"?
Луи Мэддокс
1
@ Yihui это работает для меня в выводе html, но не в результирующем .mdфайле, если у меня есть keep_md: trueв заголовке YAML. Любое решение для этого?
Мэтт С.М.
7
Для любых других американцев date: "`r format(Sys.time(), '%B %d, %Y')`".
Убомб
Привет @ Yihui, я получил искаженный месяц в выводе даты в PDF-файл. У вас есть идеи, как я могу решить эту проблему? Спасибо.
HW-ученый
2
Если вам нужна точка в дате, имейте в виду, чтобы избежать их и избежать побегов:r format(Sys.time(), '%d\\\\. %B %Y')
BurninLeo
72

Просто следите за @Yihui. Как ни странно, я обнаружил, что:

'`r format(Sys.Date(), "%B %d, %Y")`'

работает лучше чем:

"`r format(Sys.Date(), '%B %d, %Y')`"

В последнем случае RStudio выбирает изменение внешних кавычек на 'любое переключение между выводом HTML и PDF и, таким образом, нарушение кода.

Джон М
источник
1
Должен ли был быть обратный слеш?
Почему
4
Обратных слешей быть не должно. Без них код работает.
Ракенси
1
согласовано. "" не работал для меня, но "сделал. Спасибо!
Лия Вассер
18

Или просто одинарные кавычки двойные кавычки и наоборот, это хорошо работает.

---
title: "Sample Document"
output:
  html_document:
    toc: true
    theme: united
date: '`r format(Sys.time(), "%d %B, %Y")`'
author: baptiste
---
SabDeM
источник
12

Один из обходных путей - использовать brewпакет и написать свой brewшаблон YAML в качестве шаблона.

---
title: "Sample Document"
output:
  html_document:
    toc: true
    theme: united
date: <%= format(Sys.time(), "%d %B, %Y") %>
author: baptiste
---

Теперь вы можете использовать brew_n_renderфункцию, которая будет предварительно обрабатывать документ с использованием, brewа затем запускать через rmarkdown.

brew_n_render <- function(input, ...){
  output_file <- gsub("\\.[R|r]md$", ".html", input)
  brew::brew(input, 'temp.Rmd');  on.exit(unlink('temp.Rmd'))
  rmarkdown::render('temp.Rmd', output_file = output_file)
}

Чтобы заставить это работать с KnitHTMLкнопкой в ​​RStudio, вы можете написать собственный формат вывода, который будет автоматически использоваться brewв качестве препроцессора. Использование brewдля предварительной обработки гарантирует, что knitrфрагменты кода в вашем документе не будут затронуты на этапе предварительной обработки. В идеале rmarkdownпакет должен предоставлять метаданные в своем API и позволять пользователям запускать их через пользовательские функции.

Ramnath
источник
5
спасибо Рамнат, это сработает. Было бы неплохо не иметь лишних шагов и временных файлов в рабочем процессе; по моему опыту, чем более запутанным является процесс, тем меньше он воспроизводим (т.е. я не могу вспомнить, как он работает) несколько месяцев спустя.
крестить
3

или, возможно, что-то вроде следующего, см. R Markdown Parameterized Reports

params:
  reportDate:
    input: date
    label: 'Report Date:'
    value: as.POSIXct(Sys.Date())
Просто еще один
источник
1

введите описание изображения здесьПо той же проблеме для меня. Я решаю это с помощью этого кода.

---
title: "bla bla"
author: "My name"
date: \`r format(Sys.Date(), "%B %d, %Y")`\
output: html_document
---

Обновление Вы также можете использовать другой формат.

---
title: "bla bla"
author: "My name"
date: \`r format(Sys.Date(), "%m %d,%Y")`\
output: html_document
---

Лучший.

Сабля буабид
источник
-1

Я был укушен этим сегодня. я имел

date: "`r format(Sys.Date(), "%B %d, %Y")`"

и получил более-менее ту же ошибку, что и ОП, но только при вязании на слово. Вязание в PDF было хорошо, прежде чем я пытался вязать в Word. Впоследствии это тоже не сработало.

Error in yaml::yaml.load(front_matter) : 
  Scanner error: while scanning for the next token at line 3, column 31
 found character that cannot start any token at line 3, column 31
Calls: <Anonymous> ... output_format_from_yaml_front_matter -> 
       parse_yaml_front_matter -> <Anonymous> -> .Call`

Позиция 31 - первый знак%

Заменить это на

date: '`r format(Sys.Date(), "%B %d, %Y")`'

как советовал MLaVoie, работал нормально.

Я понятия не имею, почему это произошло, и у меня нет времени копаться - отчеты заканчиваются.

astaines
источник