Data atual do YAML em rmarkdown

247

Gostaria de saber se existe um truque para colocar a data atual no front-matéria do YAML de um .rmddocumento a ser processado knitre ormarkdown pacote. Eu costumava ter a seguinte linha no topo das minhas páginas wiki,

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

e seria convertido para baptiste, em 3 de maio de 2014 na saída html. Agora, eu gostaria de tirar proveito do wrapper pandoc avançado fornecido por rmarkdown, mas ter o código r no cabeçalho YAML parece não funcionar:

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

Alguma solução alternativa?

baptiste
fonte
7
Estou surpreso que isso não funcione mais, pois é exatamente isso que eu costumava fazer. Vou ver o que estava acontecendo recentemente. BTW, o yaml também suporta valores calculados a partir de R via !expr, por exemplo date: !expr Sys.time(), mas agora isso também não funciona.
Yihui Xie

Respostas:

366

Isso é um pouco complicado, mas você só precisa validar o datecampo no YAML citando a expressão R in-line, por exemplo

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

Então o erro de análise desaparecerá e a data será gerada na saída da remarcação para que o Pandoc possa usar o valor de Sys.time().

Yihui Xie
fonte
Eu acho que isso significa que o R inline não pode ser usado para, por exemplo, uma lista, includes: after_body: [ ... ]pois o YAML válido seria apenas uma string de nome de arquivo ... Portanto, não há possibilidade de includes: "`r list.files(...)`"?
Louis Maddox
1
@ Yihui isso funciona para mim na saída html, mas não no .mdarquivo resultante se eu tiver keep_md: trueno cabeçalho YAML. Alguma solução para isso?
Matt SM
7
Para quaisquer outros americanos: date: "`r format(Sys.time(), '%B %d, %Y')`".
ubomb
Oi @Yihui, eu tenho meses ilegíveis na saída da data no arquivo pdf. Você tem alguma idéia de como posso resolver esse problema? Obrigado.
HW-Scientist
2
Se você precisar de um ponto na data, lembre-se de r format(Sys.time(), '%d\\\\. %B %Y')
evitá-
72

Apenas acompanhando @Yihui. Estranhamente, eu descobri que:

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

funciona melhor que:

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

Para este último, o RStudio decide alterar as aspas externas para 'sempre que alternar entre a saída HTML e PDF e, assim, quebrar o código.

John M
fonte
1
A barra invertida deveria estar lá?
cwhy
4
As barras invertidas não devem estar lá. Sem eles, o código funciona.
Rakensi 26/05
1
acordado. "" não funcionou para mim, mas '' funcionou. obrigado!
Leah Wasser
18

Ou apenas aspas simples, aspas duplas e vice-versa, isso funciona bem.

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

Uma solução alternativa é usar o brewpacote e escrever o assunto da frente do YAML como um brewmodelo.

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

Agora você pode usar uma brew_n_renderfunção que pré-processa o documento usando brewe depois é executada 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)
}

Para fazer isso funcionar com o KnitHTMLbotão no RStudio, você pode escrever um formato de saída personalizado que será usado automaticamente brewcomo pré-processador. Usar brewpara pré-processar garante que os knitrblocos de código do seu documento sejam intocados durante o estágio de pré-processamento. Idealmente, o rmarkdownpacote deve expor os metadados em sua API e permitir que os usuários os executem por meio de uma função personalizada.

Ramnath
fonte
5
obrigado Ramnath, isso funcionaria. Seria bom não ter etapas extras e arquivos temporários no fluxo de trabalho; na minha experiência, quanto mais complicado o processo, menos ele é reproduzível (ou seja, não me lembro como funciona) alguns meses depois.
Baptiste
1

insira a descrição da imagem aquiPara o mesmo problema para mim. Eu resolvo isso usando este código.

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

Atualizar Você também pode usar outro formato.

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

Melhor.

Sabre bouabid
fonte
-1

Fui mordido por isso hoje. eu tinha

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

e obteve mais ou menos o mesmo erro do OP, mas apenas ao tricotar com palavras. Tricotar em pdf estava bom antes de eu tentar tricotar no Word. Depois também não funcionou.

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`

A posição 31 é o primeiro sinal de%

Substituindo isso por

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

como recomendado pelo MLaVoie, funcionou bem.

Não tenho idéia do por que isso aconteceu e não tenho tempo para cavar - os relatórios devem terminar.

astaines
fonte