Bieżąca data YAML w rmarkdown

247

Zastanawiam się, czy jest jakiś sposób na umieszczenie bieżącej daty na froncie YAML .rmddokumentu, który ma być przetwarzany, knitri rmarkdownpaczki. Kiedyś na górze moich stron wiki znajdował się następujący wiersz:

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

i zostałby przekonwertowany na baptiste, 3 maja 2014 r. w danych wyjściowych HTML. Teraz chciałbym skorzystać z zaawansowanego opakowania pandoc dostarczonego przez rmarkdown, ale wydaje się, że kod rw nagłówku YAML nie działa:

---
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

Jakieś obejście?

baptiste
źródło
7
Dziwi mnie, że to już nie działa, ponieważ tak właśnie robiłem. Zobaczę, co się ostatnio działo. BTW, yaml obsługuje również wartości wyliczone z R przez !exprnp. date: !expr Sys.time(), Ale teraz to też nie działa.
Yihui Xie

Odpowiedzi:

366

Jest to trochę trudne, ale wystarczy, że datepole będzie poprawne w YAML, cytując wbudowane wyrażenie R, np.

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

Następnie błąd parsowania zniknie, a data zostanie wygenerowana w wyniku przeceny, aby Pandoc mógł użyć wartości z Sys.time().

Yihui Xie
źródło
Myślę, że to oznacza, że ​​wbudowanego R nie można użyć np. Do listy, includes: after_body: [ ... ]ponieważ prawidłowy YAML będzie tylko ciągami nazw plików ... Więc nie ma takiej możliwości includes: "`r list.files(...)`"?
Louis Maddox,
1
@Yihui to działa dla mnie w pliku wyjściowym HTML, ale nie w .mdpliku wynikowym , jeśli mam keep_md: truew nagłówku YAML. Jakieś rozwiązanie tego?
Matt SM
7
Dla innych Amerykanów: date: "`r format(Sys.time(), '%B %d, %Y')`".
ubomb
Cześć @Yihui, Mam zniekształcony wynik miesiąca w pliku pdf. Czy masz pomysł, jak rozwiązać ten problem? Dziękuję Ci.
HW-Scientist
2
Jeśli potrzebujesz kropki w dacie, pamiętaj o ich ucieczce i ucieczce przed ucieczką:r format(Sys.time(), '%d\\\\. %B %Y')
BurninLeo
72

Po prostu śledzę na @Yihui. Co dziwne, odkryłem, że:

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

działa lepiej niż:

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

W tym drugim przypadku RStudio decyduje się na zmianę zewnętrznych cytatów za 'każdym razem, gdy przełącza się między wyjściem HTML a PDF, a tym samym łamie kod.

John M.
źródło
1
Czy ukośnik miał tam być?
cwhy
4
Odwrotne ukośniki nie powinny tam być. Bez nich kod działa.
rakensi
1
Zgoda. „” nie działało dla mnie, ale „” zadziałało. Dziękuję Ci!
Leah Wasser
18

Lub po prostu cytat podwójny cytat i odwrotnie, to działa dobrze.

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

Jednym z obejść tego problemu jest użycie brewpakietu i napisanie frontu YAML jako brewszablonu.

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

Możesz teraz użyć brew_n_renderfunkcji, która wstępnie przetworzy dokument za pomocą, brewa następnie uruchomi go 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)
}

Aby to działało z KnitHTMLprzyciskiem w RStudio, możesz napisać niestandardowy format wyjściowy, który będzie automatycznie używany brewjako preprocesor. Użycie brewdo wstępnego przetwarzania zapewnia, że knitrfragmenty kodu w dokumencie pozostaną nietknięte podczas etapu wstępnego przetwarzania. W idealnym przypadku rmarkdownpakiet powinien ujawniać metadane w interfejsie API i umożliwiać użytkownikom uruchamianie go za pomocą funkcji niestandardowej.

Ramnath
źródło
5
dzięki Ramnath, to by działało. Byłoby miło nie mieć dodatkowych kroków i plików tymczasowych w przepływie pracy; z mojego doświadczenia wynika, że ​​im bardziej skomplikowany jest proces, tym mniej jest powtarzalny (tj. nie pamiętam, jak działa) kilka miesięcy później.
baptiste
1

wprowadź opis zdjęcia tutajZa ten sam problem dla mnie. Rozwiązuję go za pomocą tego kodu.

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

Aktualizacja Możesz także użyć innego formatu.

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

Najlepsza.

Saber bouabid
źródło
-1

Ugryzło mnie to dzisiaj. miałem

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

i otrzymywał mniej więcej ten sam błąd co OP, ale tylko podczas dziania z słowem. Knitting do pdf był w porządku, zanim spróbowałem dziać z Wordem. Potem też nie działało.

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`

Pozycja 31 jest pierwszym znakiem%

Zastępując to

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

zgodnie z zaleceniami MLaVoie, działało dobrze.

Nie mam pojęcia, dlaczego tak się stało, i nie mam czasu na kopanie - raporty do końca.

astaines
źródło