Arquivo

Archive for the ‘sweave’ Category

Gerar provas diferentes com Sweave

Método japonês para evitar a cola.

Há muito tempo que eu procurava uma forma de gerar provas diferentes por meio de um processo de sorteio aleatório. Eu não queria fazer duas provas, tirar cópias delas e distribuir. Eu queria uma prova diferente da outra, sem cópias, entende? Bem, no começo pensei que isso fosse algo extremamente difícil mas não é! Nos vamos fazer isso com Sweave, que é o mecanismo de acoplar o R (ambiente de computação estatística) ao LaTex (editor de textos).

O procedimento é bem simples e eu vou descrevê-lo em etapas:

  • Etapa 1. Criamos um arquivo Sweave (extensão *.Rnw) e colocamos os enunciados da nossa prova. Esse arquivo não precisar ter preâmbulo, apenas o conteúdo da prova. Como exemplo, considere o conteúdo abaixo que deve ser salvo em um arquivo do Sweave (prova.Rnw). Note que a função sample() é a responsável pela aleatoriedade das questões. Com isso, em cada compilação teremos enunciados diferentes, cada um deles com mesma probabilidade de ocorrer;
  • <<echo=false, results=hide>>=
    r <- sample(1:2, 1)
    conf <- list(A="da mesma cor", B="de cor diferente")
    x <- conf[[r]]
    @ 
    
    \noindent 1. Pega-se um baralho e coloca-se os quatro ases na mesa, virados 
    para baixo. Dois deles (A$\clubsuit$, A$\spadesuit$) são pretos, os outros 
    dois (A$\heartsuit$, A$\diamondsuit$) são vermelhos. Seja o experimento
    retirar duas dessas quatro cartas aleatoriamente. Qual a probabilidade das 
    cartas serem \Sexpr{x}?
    
    <<echo=false, results=hide>>=
    r <- sample(1:2, 1)
    conf <- list(A=c(2,2), B=c(3,2.5))
    symb <- c(0,0,1,conf[[r]][1])
    symbb <- paste("|", paste(symb, collapse="|"), "|", sep="")
    cust <- conf[[r]][2]
    @ 
    
    \vspace{2cm}
    \noindent 2. Uma máquina caça níquel possui 2 cilíndros e em cada uma deles
    está gravado a sequência de números \Sexpr{symbb}. A máquina premia o jogador
    com o valor da soma dos números observados, ou seja, se sair | 1 | 0 | o
    jogador ganha 1 dólar. O valor de cada jogada é \Sexpr{cust} dólares. Seja
    $X$ o \textbf{lucro} do jogador em cada jogada. Determine:
    \begin{compactenum}[a)]
      \item A distribuição de probabilidades de $X$;
      \item O lucro médio do jogador, ou seja, o valor esperado de $X$.
    \end{compactenum}
    
  • Etapa 2. Criamos um arquivo R para fazermos a compilação repetida do arquivo prova.Rnw. Cada resultado de compilação será salvo em um diretório dentro ao atual (./cada_tex) com nome de arquivos diferentes (prova1.tex, prova2.tex, etc). Nessa mesma etapa nos geramos um arquivo todos_inputs.tex que nada mais é que a chamada de cada prova para compilação que será usada no arquivo *.tex da etapa a seguir;
  • # cria o diretório para os arquivos compilados
    dir.create("cada_tex")
    # número de provas e o nome das provas
    n <- 10
    names <- paste("cada_tex/prova", 1:n, ".tex", sep="")
    # função para compilar com nomes de saída diferente
    do.tex <- function(name){
      Sweave("prova.Rnw", encoding="utf8", output=name)
    }
    sapply(names, do.tex)
    # para gerar um arquivo tex com os inputs
    sink("todos_inputs.tex")
    for(i in names){
      cat(paste("\\input{", i, "}\n", sep=""))
      cat("\\newpage\n")
    }
    sink()
    # para compilar o arquivo tex
    system("pdflatex provas.tex")
    
  • Etapa 3. Agora nos compilamos de *.Rnw para *.pdf. Esse arquivo (provas.tex) contém o preâmbulo que precisamos e o input de cada uma das provas, uma por página.
  • \documentclass[a4paper,10pt]{article}
    \usepackage{Sweave}
    \usepackage[utf8]{inputenc}
    \usepackage[brazil]{babel}
    \usepackage[T1]{fontenc}
    \usepackage{enumerate}
    \usepackage{paralist}
    
    \begin{document}
    \pagestyle{empty}
    
    \input{todos_inputs.tex}
    
    \end{document}
    

    Ao executar essas etapa no seu computador, verifique a codificação dos arquivos. Como eu uso linux, minha codificação é a padrão do SO (utf-8). No mais é só aproveitar. Até a próxima ridícula.

    Anúncios
    Categorias:sweave

    Usando Sweave para fazer figuras com tikz integrado o GNUplot

    Printscreen do documento pdf final.

    Tikz é um pacote LaTeX para fazer figuras. As figuras são feitas por comandos assim como fazemos os gráficos no R. Porém, as opções da tikz vão além de gráficos de exploração gráfica ou de resultados como os do R. É possível fazer figuras bem complexas e de alta qualidade tipográfica com esse pacote. Veja os exemplos.

    Para gráfico de funções paramétricas, o tikz passa o trabalho para o gnuplot fazer. É uma integração que permite combinar a poderosa ferramenta gráfica que é o gnuplot com a qualidade tipográfica do tikz.

    Para melhorar ainda mais, podemos usar o Sweave para controlar os componentes do gráfico que o tikz vai passar para o gnuplot. É um que passa para o outro, que passa para o outro… trabalho em equipe! Aqui então surge uma pergunta: se é para usar Sweave, por que não fazer os gráficos com o R e incluí-los no documento? Primeiro, vamos aprender uma forma equivalente de fazer gráficos simples com o tikz-gnuplot, basicamente aqueles que fazemos com a função curve() do R. Segundo, com tikz-gnuplot a figura fica com o mesmo tipo de fonte do texto. (Ainda podemos exportar figuras usando o pacote tikzDevice, veja esse post).

    O CMR desse post é um arquivo *.Rnw, típico de documento Sweave. Para que tudo funcione você terá que ter instalado o pgf/tikz e o gnuplot. Para instalá-los, abra um terminal linux e faça

    $ sudo apt-get install pgf gnuplot
    

    Para compilar Rnw -> tex, faça

    $ R CMD Sweave foo.Rnw
    

    Para compilar tex -> pdf, faça

    $ pdflatex --shell-escape foo.tex
    

    em que a opção --shell-escape é para permitir que o latex chame o gnuplot. Caso não coloque essa opção, nada que use o gnuplot aparecerá no documento compilado. Salve o conteúdo abaixo em um documento com extensão *.Rnw.

    Nesse documento eu gero a mesma figura de duas formas: 1) empregando o gnuplot e 2) usando as capacidades gráficas do próprio tikz. Você não verá diferença entre os gráficos (a não ser a cor) porque eles são funções simples de plotar. Pórem, o tikz por sí só não tem tanta capacidade para fazer gráficos, e para funções mais complexas só mesmo a integração do gnuplot para conseguir os objetivos. Até a próxima ridícula.

    \documentclass[a4paper,10pt]{article}
    \usepackage{Sweave}
      \SweaveOpts{eps=FALSE, keep.source=TRUE}
    \usepackage[utf8]{inputenc}
    \usepackage[brazil]{babel}
    \usepackage[T1]{fontenc}
    \usepackage{amsmath}
    \usepackage{amssymb}
    \usepackage{tikz}
      \usetikzlibrary{arrows,shadows}
    
    \begin{document}
    
    Seja $X$ uma variável aleatória com distribuição Normal padrão, ou seja,
    $X\sim \text{N}(\mu=0,\sigma=1)$. Calcule a $\Pr(\Sexpr{(xi <- -1.5)}<X<\Sexpr{(xs <- 0.75)})$
    e faça o esboço da função densidade com destaque para área correspondente ao evento de interesse.
    
    <<>>=
    pr <- pnorm(xs)-pnorm(xi)
    pr
    @
    
    \begin{center}
    % esse gráfico é feito pelo gnuplot
    \begin{tikzpicture}[domain=-3.5:3.5, yscale=4, xscale=0.5]
      \draw[very thin, color=gray, xstep=1cm, ystep=0.05cm] (-4.2,-0.02) grid (4.2,0.42);
      \begin{scope}[smooth, draw=black, y=0.3989422804cm]
        \filldraw [fill=gray!90]
          plot[id=f1,domain=\Sexpr{xi}:\Sexpr{xs}] function {exp(-x*x/2)}
          -- (\Sexpr{xs},0) node[below] {$\Sexpr{round(xs,2)}$}
          -- (\Sexpr{xi},0) node[below] {$\Sexpr{round(xi,2)}$} -- cycle;
        \draw[black] plot[id=f7, domain=-3.5:3.5, samples=100]
        function {exp(-x*x/2)};
        \draw[->] (-4.2,0) -- (4.2,0) node[below right] {};            
        \draw (0,0) -- (0,1) node[above] {};
      \end{scope}
    \end{tikzpicture}
    % esse gráfico é feito pelo tikz, sem gnuplot
    \begin{tikzpicture}[domain=-3.5:3.5, yscale=4, xscale=0.5]
      \draw[very thin, color=gray, xstep=1cm, ystep=0.05cm] (-4.2,-0.02) grid (4.2,0.42);
      \draw[color=red] plot (\x,{0.4*exp(-0.5*\x*\x)});
      \filldraw[fill=red] plot[domain=\Sexpr{xi}:\Sexpr{xs}] (\x,{0.4*exp(-0.5*\x*\x)})
        -- (\Sexpr{xs},0) node[below] {$\Sexpr{round(xs,2)}$}
        -- (\Sexpr{xi},0) node[below] {$\Sexpr{round(xi,2)}$} -- cycle;
      \draw[->] (-4.2,0) -- (4.2,0);
      \draw (0,0) -- (0,0.4);
    \end{tikzpicture}
    \end{center}
    
    \end{document}
    
    Categorias:sweave, tikz Tags:, ,

    Animações em documentos PDF produzidos com Sweave

    Animação que representa as probabilidades obtidas pela tabela da distribuição normal padrão.

    O pacote do animate do \LaTeX, desenvolvido por Alexander Grahn, permite que sejam inseridas animações em documentos PDF. Esses arquivos devem ser visualizados em leitores de PDF da Adobe. No Linux podemos usar o acroread.

    O procedimento é simples. Vou fazer isso em um documento Sweave. Primeiro confeccionamos diversas figuras que formam uma seqüência de ações. Tais figuras podem ser feitas com controladores de fluxo como a função for() e similares. Inclusive, o pacote animation do R, desenvolvido por Yihui Xie, oferece implementações para confecção de animações. As figuras são salvas em um diretório. Para adicioná-las ao documento na forma de animação (com botões de play, stop) basta usar o comando \animategraphics{}.

    O arquivo Sweave abaixo (*.Rnw) gera um arquivo PDF com a tabela da distribuição normal padrão e uma animação que representa a área integrada correspondente aos valores da tabela. Veja o PDF. Para gerar gifs animados como R veja o artigo do Mark Heckmann no R you ready?. Até a próxima ridícula.

    \documentclass[a4paper]{article}
    \usepackage[brazil]{babel}
    \usepackage{Sweave}
    \usepackage{animate}
    \thispagestyle{empty}
    
    \begin{document}
    
    \begin{center}
    {\Large Tabela da distribui\c{c}\~{a}o normal padr\~{a}o}\\ \vspace{2ex}
    {\large Walmes Zeviani -- LEG/UFPR}  \\
    \end{center}
    
    <<echo=false, results=hide>>=
    #-----------------------------------------------------------------------------
    dir.create("exemplos")
    png(file="exemplos/qnorm%1d.png", width=500, height=250)
    par(mar=c(4,4,1,1))
    for(q in seq(0, 4,l=100)){
      curve(dnorm(x, 0, 1), -5, 5, ylab="f(z)", xlab="z")
      x <- seq(0, q, by=0.01)
      fx <- dnorm(x, 0, 1)
      polygon(c(x, rev(x)),
              c(fx, rep(0, length(fx))),
              col="gray90")
      abline(v=0, lty=2)
      Pr <- round(pnorm(q, 0, 1)-0.5, digits=3)
      qq <- round(q, digits=3)
      legend("topleft", bty="n", fill="gray90",
             legend=substitute(P(0<~Z<=~q)==Pr, list(q=qq, Pr=Pr)))
    }
    dev.off()
    #-----------------------------------------------------------------------------
    @ 
    
    <<echo=false, results=hide>>=
    #-----------------------------------------------------------------------------
    require(xtable)
    options(OutDec=",")
    q <- seq(0,3.99,by=0.01)
    p <- pnorm(q)-0.5
    m <- matrix(p, byrow=TRUE, ncol=10)
    rownames(m) <- gsub("\\.", ",", formatC(seq(0,3.9,0.1), dig=1, format="f"))
    colnames(m) <- 0:9/100
    #-----------------------------------------------------------------------------
    @
    
    \begin{center}
    \animategraphics[controls, loop, width=0.75\textwidth]{10}{exemplos/qnorm}{1}{100}
    \end{center}
    
    \begin{center}
    \small\addtolength{\tabcolsep}{-3pt}
    {\footnotesize
    <<echo=false, results=tex>>=
    #-----------------------------------------------------------------------------
    print(xtable(m, digits=5), floating=FALSE)
    #-----------------------------------------------------------------------------
    @ 
    }
    \end{center}
    \end{document}
    
    

    Tabelas com formatação condicional com Sweave

    Tabela condicional gerada com Sweave.

    Tabelas com formatação condicional permitem que você extraia a informação presente mais rápido. Com o Sweave, lógico, é possível apresentar tabelas com formatação. Basta que você faça uma função que formate adequadamente o valor das cédulas. No arquivo Sweave abaixo (salvar com extensão *.Rnw) eu preparo um exemplo reproduzível de como publicar as notas dos alunos. Com a cor azul serão as notas maiores ou iguais a sete, e cor vermelha nos casos contrários.

    O grande truque é usar a opção sanitize.text.function=function(x){x} da função print.xtable() que aprendi com a ajuda do Marc Schwartz na R-help. Até a próxima ridícula.

    \documentclass{article}
    \usepackage{Sweave}
    \usepackage{color}
    \usepackage[brazil]{babel}
    
    \title{Notas nas avalia\c{c}\~{o}es de Estat\'{i}stica Computacional}
    \author{Walmes Zeviani}
    
    \begin{document}
    \maketitle
    
    <<results=tex>>=
    #-----------------------------------------------------------------------------
    da <- data.frame(aluno=c("Carlos Adriano","Elizandra Pereira"
                       "Gustavo Flioz","Melissa Hultliertz",
                       "Rodrigo Allan","Vanessa Guith","Wilson Sandro"),
                     p1=10*rbeta(7,3,2), p2=10*rbeta(7,3,2))
    
    colore <- function(x, corte=7){
      aux <- ifelse(x>=corte,
                    paste("\\textcolor{blue}{", formatC(x, dig=2, format="f"), "}"),
                    paste("\\textcolor{red}{", formatC(x, dig=2, format="f"), "}"))
      gsub("\\.", ",", aux)
    }
    
    da <- cbind(aluno=da$aluno, as.data.frame(apply(da[,-1], 2, colore)))
    
    require(xtable)
    
    caption <- "Notas nas avalia\\c{c}\\~oes."
    print(xtable(da, caption=caption),
          sanitize.text.function=function(x){x},
          caption.placement="top", include.rownames=FALSE)
    #-----------------------------------------------------------------------------
    @ 
    
    \end{document}
    
    Categorias:sweave Tags:, , ,

    Sweave com gráficos do R em tikz

    Gráfico feito pelo R mas com tradução para código tikz. A fonte usada é a nativa do LaTeX.

    O Sweave é a ferramenta que permite a edição textos em LaTeX, de alta qualidade diagramática, com a inclusão de códigos R. Isso facilita muito a vida de quem precisa gerar relatórios de análises, material didático sobre estatística, dissertação e teses com temas afins.

    Tikz (e PGF) é um pacote LaTeX desenvolvido pelo Professor Till Tantau para fazer gráficos a partir de códigos. Os códigos são interpretados e no documento gerado são inseridas as figuras. A vantagem de fazer figuras usando os recursos do tikz é que elas ficam altamente compatíveis com aspectos do texto, por exemplo, a fonte (tipo, tamanho) dos gráficos é a mesma do texto. Além disso, o seu arquivo *.tex é auto suficiente, pois as figuras são geradas a partir dele, não precisam estar no seu diretório ocupando espaço, ou que aumenta a portabilidade. Para instalar esse pacote do LaTeX, abra uma janela de terminal Linux e digite

    sudo apt-cache search pgf # lista a busca com esse termo
    sudo apt-get install pgf  # faz a instalação do pacote
    

    O pacote tikzDevice do R, desenvolvido por Charlie Sharpsteen e Cameron Bracken, faz conversão de um gráfico do R em código tikz. Dessa forma, podemos importar o arquivo gerado e ter os gráficos do R dentro um documento feito em LaTex com as definições de texto e expressões matemáticas (com letras gregas, integrais, somatórios, frações, etc). Para instalar esse pacote, abra uma sessão R e digite

    install.packages("tikzDevice", dep=TRUE)
    

    Se você já usa sweave não vai ter dificuldades de usar os dois procedimentos que vou apresentar. O primeiro deles no chunk eu faço o gráfico, exporto com a função tikz() e a figura é gerada somente na compilação tex -> pdf. No segundo, no chunk eu exporto com a função tikz() mas num arquivo *.tex sozinho, que é compilado separado, ou seja, a figura é gerada pelo próprio R no momento da compilação Rnw -> tex. Um código mínimo para o primeiro procedimento está abaixo.

    \documentclass{article}
    
    \usepackage{Sweave}
    \usepackage{tikz}
    
    \SweaveOpts{keep.source=true}
    
    \title{Usando ti\textit{k}z no Sweave}
    \author{Walmes Zeviani\\ LEG/UFPR}
    \date{3 de Junho de 2011}
    
    \begin{document}
    
    \maketitle
    
    C\'{o}digo m\'{i}nimo reproduz\'{i}vel usando \texttt{tikzDevice}
    para exportar gr\'{a}ficos feitos no R para codifica\c{c}\~{a}o ti\textit{k}z.
    
    {\footnotesize
    <<>>=
    #------------------------------------------------------------------------------------------
    
    require(tikzDevice)
    set.seed(2011); x <- rnorm(200)
    tikz("plot.tex", w=5, h=3)
    hist(x, freq=FALSE, ylab="Densidade",
    main="Histograma de uma amostra de $X \\sim N(\\mu=0, \\sigma^2=1)$")
    curve(dnorm(x), col=2, add=TRUE, lwd=2); rug(x)
    legend("topleft", col=2, lty=1, lwd=2, bty="n",
    legend="$\\displaystyle \\frac{1}{\\sqrt{2\\pi\\sigma^2}}\\cdot e^{-\\frac{(x-\\mu)^2}{2\\sigma^2}}$")
    box(); dev.off()
    
    #------------------------------------------------------------------------------------------
    @
    }
    
    \input{plot.tex}
    
    \end{document}
    

    Para compilar esse arquivo Rnw -> tex, tex -> pdf, abra uma sessão do terminal Linux no diretório do arquivo e digite

    R CMD Sweave arquivo.Rnw
    pdflatex arquivo.tex
    

    Pronto! Com isso seu arquivo pdf foi gerado (veja o meu arquivo). O procedimento abaixo corresponde ao segundo que mencionei.

    \documentclass{article}
    
    \usepackage{Sweave}
    \usepackage{tikz}
    
    \SweaveOpts{keep.source=true}
    
    \title{Usando ti\textit{k}z no Sweave}
    \author{Walmes Zeviani\\ LEG/UFPR}
    \date{3 de Junho de 2011}
    
    \begin{document}
    
    \maketitle
    
    C\'{o}digo m\'{i}nimo reproduz\'{i}vel usando \texttt{tikzDevice}
    para exportar gr\'{a}ficos feitos no R para codifica\c{c}\~{a}o ti\textit{k}z.
    
    {\footnotesize
    <<>>=
    #------------------------------------------------------------------------------------------
    
    require(tikzDevice)
    
    set.seed(2011); x <- rnorm(200)
    tikz("plot2.tex", w=5, h=3, standAlone=TRUE,
    packages=c("\\usepackage{tikz}",
    "\\usepackage[active,tightpage,psfixbb]{preview}",
    "\\PreviewEnvironment{pgfpicture}",
    "\\setlength\\PreviewBorder{0pt}"))
    hist(x, freq=FALSE, ylab="Densidade",
    main="Histograma de uma amostra de $X \\sim N(\\mu=0, \\sigma^2=1)$")
    curve(dnorm(x), col=2, add=TRUE, lwd=2); rug(x)
    legend("topleft", col=2, lty=1, lwd=2, bty="n",
    legend="$\\displaystyle \\frac{1}{\\sqrt{2\\pi\\sigma^2}}\\cdot e^{-\\frac{(x-\\mu)^2}{2\\sigma^2}}$")
    box(); dev.off()
    
    tools::texi2dvi("plot2.tex", pdf=TRUE)
    
    #------------------------------------------------------------------------------------------
    @
    }
    
    \includegraphics{plot2.pdf}
    
    \end{document}
    

    A diferença é que o segundo procedimento cria figuras no seu diretório. Dependendo da tarefa, você pode usar o Sweave de uma forma ou de outra, até mesmo combinando entre elas. Até a próxima ridícula.

    Categorias:gráficos, sweave, tikz Tags:, ,

    Dicas para compilar Sweave no Linux

    Sweave é o ponto de encontro entre o R e LaTeX. É uma ferramenta de edição de texto que combina o poder e elegância do LaTeX para edição de textos científicos com o as funcionalidades do aplicativo (mais que) estatístico R. Nesse post vamos apresentar dicas para compilar arquivos de extensão *.Rnw no terminal do Linux.

    Considere que existe um arquivo mysweave.Rnw em um diretório de trabalho do seu Linux. Crie um arquivo de extensão *.sh que basicamente é um arquivo com comandos que são aplicados na linha do terminal do Linux. Use o nome swv.sh (acrônimo de sweave) e cole nele o conteúdo abaixo.

    #!/bin/sh
    # compila o arquivo *.Rnw gerando um *.tex
    echo "library(tools); Sweave(paste(\"$1\",'.Rnw', sep=''))" | R --no-save --no-restore;
    # compila o arquivo *.tex gerando um arquivo *.dvi
    latex $1.tex
    # compila o arquivo *.bib que contém as bibliografias
    bibtex $1
    # compila o arquivo *.tex gerando um arquivo *.pdf
    pdflatex $1.tex
    

    Cada comando do arquivo swv.sh contém um comentário acima da respectiva ordem que identifica a ação. O arquivo swv.sh deve estar no mesmo diretório do arquivo mysweave.Rnw e será onde os demais arquivos serão criados.

    Nesse passo criaremos uma alias para o arquivo swv.sh. Para isso, vá no seu diretório pessoal (home) e edite o arquivo .bashrc (é um arquivo oculto). Adicione nesse arquivo as linhas abaixo.

    # atalho para compilar *.Rnw
    alias swv="./swv.sh"
    

    Para compilar o seu arquivo mysweave.Rnw basta executar o comando swv no seu diretório de trabalho dessa forma

    $ swv mysweave
    

    Não é necessária a inclusão da extensão *.Rnw. É esperado que os respectivos arquivos mysweave.dvi e mysweave.pdf sejam gerados.

    É possível definir esse atalho globalmente. Para isso, cole o arquivo swv.sh no diretório /bin. Para usar, na linha de comando faça

    $ swv.sh mysweave
    

    Dessa forma não é necessário ter o arquivo swv.sh em todo diretório com arquivos *.Rnw.

    Categorias:linux, sweave Tags:, , , , ,