Inserindo tabelas no LaTex de forma dinâmica

Para aqueles que já trabalharam com geração de números aleatórios, a situação a seguir pode ser rotineira: Você escreve um script e sempre que o executa gera outputs diferentes. Caso esteja usando uma semente para a geração destes número aleatórios talvez o problema não seja tão grave, mas se por algum motivo a aleatoriedade for importante então escrever resultados sobre isso pode ser um problema. 

Imagine a seguinte situação: Você gera um bocado de números aleatórios, calcula uma série de estatísticas e escreve um belo texto sobre todas elas. Mas depois você percebe que podia ter feito algo a mais. Desta forma, lá se inicia o ciclo vicioso sem prazo para término. Caso exista algo a mais a ser feito então isso irá significar uma longa e torturante sessão, executando os mesmos códigos para inserir tabelas, gerar gráficos e etc. Mas aqui estamos nós para mostrar-lhe que existe uma opção de deixar o torturante trabalho mais agradável (e fácil).

A motivação deste post é deixar claro uma filosofia de vida a ser seguida. Perder tempo com coisas banais (como por exemplo ficar atualizando uma tabela de valores aleatórios) é perda de tempo e tem como ser evitada, afinal é muito mais interessante e produtivo perder tempo pensando em análises/conclusões sobre os resultados.  E para fazer isso, vamos utilizar o próprio tex e o R. O R será fundamental, pois ele será responsável por gerar as tabelas no formato tex. Obs.: O arquivo .tex e o .R devem estar na mesma pasta.

Então vamos lá. O primeiro passo é criar um arquivo .tex.

 % artigo.tex
\documentclass[paper=a4, fontsize=11pt]{article} % A4 paper and 11pt font size
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{latexsym}        
\usepackage[utf8]{inputenc}
\usepackage[brazil]{babel}
\usepackage{amsmath,amsthm} % Math packages

\begin{document}
Um exemplo de documento.

\end{document}

Após feito isso e compilar o artigo.tex, teremos um documento não tão bonito, mas funcional. Caso você, caro leitor, tenha um layout mais agradável, pode utilizá-lo sem peso na consciência. Feito isso, vamos ao R criar uma função que recebe um dataframe e gera um arquivo .tex com informações de uma tabela. O primeiro passo é instalar o pacote xtable. Para quem não conhece, o xtable é capaz de transformar um dataframe do R em uma tabela tex. E tudo isso em um passe de mágica.

Então tudo que deve ser feito é pegar o dataframe com as estatísticas que você precisa calcular, imprimi-lo em um arquivo de texto, e anexá-lo ao tex. A função abaixo recebe um dataframe, o transforma em uma tabela e salva com um devido nome.

# gera_tabela.R
imprime_tabela = function(dados, nome_arquivo)
{
    dataframe_tex = xtable::xtable(dados)
    sink(nome_arquivo)
    print(dataframe_tex)
    sink()
}

imprime_tabela(head(cars), 'teste.tex')

Se chamarmos "imprime_tabela(head(cars), 'teste.tex')", será gerado, no seu diretório de trabalho um arquivo com o nome de teste.tex e com as primeiras seis linhas do dataset cars. A geração deste arquivo, é feita utilizando a função sink() que cria um arquivo e tudo que é impresso pelo R também é inserido naquele arquivo (no nosso caso, o arquivo teste.tex). Agora precisamos voltar ao arquivo principal do tex e inserir essa tabela lá de forma que não seja necessário ficar copiando e colando e sim fazer referência a um arquivo que contém a tabela desejada. Basta inserir no arquivo .tex principal o comando \input{nome_da_tabela}, que vai "anexar" as informações do arquivo no seu conteúdo principal. O novo código seria assim:

% artigo.tex
\documentclass[paper=a4, fontsize=11pt]{article} % A4 paper and 11pt font size

\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{latexsym}        
\usepackage[utf8]{inputenc}
\usepackage[brazil]{babel}

\usepackage{amsmath,amsthm} % Math packages

\begin{document}
Um exemplo de documento.
\input{teste.tex}

\end{document}

Agora não é mais necessário nos preocuparmos em copiar e colar a tabela toda vez no tex, basta modificar o arquivo teste.tex. Se rodarmos no R, por exemplo  "imprime_tabela(tail(cars), 'teste.tex')" e compilarmos o tex novamente, a tabela será atualizada automáticamente.

Isso é tudo que é preciso fazer para gerar conteúdo sem a preocupação de atualizar toda vez que fizer uma modificação. Basta pensar que é necessário apenas alterar o conjunto de dados no script R e executar novamente. Com isso, todas as tabelas serão atualizadas. No exemplo dado talvez isto não tenha sido perceptível, mas em projetos maiores pode ser um verdadeiro quebra galho. Em um futuro próximo, iremos ensinar como inserir dinâmicamente outputs do R, é claro seguindo a mesma lógica. É interessante explorar trambém as opções do xtable, como por exemplo a inserção de \captions, \labels e etc.

3 comentários:

  1. Salvando monografias, dissertações e teses :)

    ResponderExcluir
  2. Muito bom o post! Recentemente, tive que fazer uma analises estatística com várias tabelas Anova.
    Pra automatiza eu fiz um código Sweave que percorria os dados em loop e salvava as informações num arquivo .tex. Quando tentei colocar uma figura para cada tabela a coisa parou de funcionar.

    O que eu gostaria de saber: é possível fazer um script em .R, .Rnw ou .tex (ou todos combinados) que gere um pdf com varias tabelas e figuras criadas em loop?

    Obrigado

    ResponderExcluir
    Respostas
    1. Sim, é possivel. Eu particularmente gosto de usar o pacote brew. Dá uma olhada. Qualquer coisa só falar. Abraços.

      Excluir