2017-12-28 47 views
1

knitR (.Rnw)을 사용하여 보고서를 작성하여 PDF로 컴파일했습니다. 모든 단일 질문에 대해 동일한 그림을 그리기 위해 for 루프에 플롯을 만들었습니다. 불행히도 PDF 파일에 경고 메시지가 나타나고 오류의 원인을 정확히 알지 못합니다 ...for-loop에서 ggplot을 사용한 플롯이 PDF로 컴파일되지 않음

여기는 문제가 시작되는 곳의 청크입니다. 루프는 R 내에서 제대로 실행되지만 PDF로 컴파일되지 않습니다 아래의 전체 코드 참조). 나는 다양한 라벨, 인쇄 기능 및 기타 물건을 시도했지만 해결책을 찾지 못했습니다.

<<echo=FALSE, warning=T, message=F>>= 

for(i in 1:3){ 
    cat(paste("\\subsection{",titel[i],"}\n", sep="")) 
    cat(paste("Figure \\ref{class",i,"} \n", sep="")) 
    cat(paste("\\begin{figure}[H] \n", sep="")) 
    cat(paste("\\begin{center} \n", sep="")) 
    cat(paste("\\includegraphics[width=1\\textwidth,", 
      "height=.47\\textheight,keepaspectratio]{class",i,".pdf}\\caption{",titel[i],"}\n", sep="")) 

    cat(paste("\\label{class",i,"}" \n, sep="")) 
    cat(paste("\\end{center} \n",sep="")) 
    cat(paste("\\end{figure} \n",sep="")) 



    p <- ggplot(data[!is.na(data$F17),], aes_string(x=Fragen[i], y="..prop..", group = "1", fill="F17"))+ 
     geom_bar()+ 
     facet_grid(F17~.)+ 
     geom_text(aes(label = scales::percent(..prop..), 
       y= ..prop..), stat= "count", vjust = -.5, size=3) + 
     ylab("Prozent")+ 
     xlab(titel[i])+ 
     scale_fill_manual(name="Individuals", values=colorScheme)#+ 
     #theme_mine 


pdfnam<-paste("class",i,".pdf",sep="") #produce a plot for each class 
pdf(file=pdfnam,width=12, height = 4) 
#gridExtra::grid.arrange(p, q) 
print(p) 
dev.off() 
} 

@ 

여기 복제에 전체 코드입니다 :

\documentclass{article} 

\usepackage{amsmath,amssymb,amstext} 
\usepackage{graphicx} 
\usepackage{geometry} 
\geometry{top=15mm, left=25mm, right=25mm, bottom=25mm,headsep=10mm,footskip=10mm} 
\usepackage{xcolor} 
\usepackage{float} 
\usepackage[T1]{fontenc} % Umlaute 
\usepackage[utf8]{inputenc} 
\inputencoding{latin1} 

\begin{document} 
\parindent 0pt 

\title{title} 
\maketitle 

<<echo=FALSE, warning=FALSE, message=FALSE>>= 
library(ggplot2) 
library(reshape) 
library(knitr) 
library(doBy) 
library(dplyr) 


opts_chunk$set(fig.path='figure/graphic-', fig.align='center', fig.show='hold',fig.pos='!ht', 
      echo=FALSE,warning = FALSE) 

@ 

<<echo=FALSE, warning=FALSE, message=F>>= 

# data and other useful stuff 

data <- data.frame(F1 = c("A", "A", "B", "C"), # answers to question 1, ... 
        F2 = c("A", "B", "B", "C"), 
        F3 = c("A", "B", "C", "C"), 
        F17 = c("K", "L", "L", "M")) # K, L and M are a certain individual. L answered twice. 

# colour scheme: 
GH="#0085CA"; H="#DA291C"; BV="#44697D" 
colorScheme <- c(BV, H, GH) 

# individual theme for plots: 
theme_mine = theme(plot.background = element_rect(fill = "white"), 
       panel.background = element_rect(fill = "white", colour = "grey50"), 
       text=element_text(size=10, family="Trebuchet MS")) 

# a vector with the variable names from "data" (F1, F2, F3). 
Fragen <- c(paste0('F',seq(1:3), sep="")) 

# question title for labeling the plots: 
titel <- c("Q1", "Q2", "Q3", "Q17") 

@ 


\begin{figure}[h] 
\begin{center} 
<<echo=FALSE, fig.width=9.6, fig.height=6, warning=FALSE>>= 

p <- ggplot(data, aes(x=F17))+ 
    geom_bar(fill = colorScheme)+ 
    xlab(titel[4])+ 
    #geom_text(aes(label = scales::percent(..prop..), 
    #   y= ..prop..), stat= "count", vjust = -.5, size=3) + 
    ylab("Absolut")+ 
    theme_bw() 
    #theme_mine # does not work properly yet. 
p 

@ 
\caption{figa} 
\label{figa} 
\end{center} 
\end{figure} 

\section{individual plots} 

<<echo=FALSE, warning=T, message=F>>= 

# here is where the problem starts: the loop runs fine within R but does not compile to an PDF. 

for(i in 1:3){ 
    cat(paste("\\subsection{",titel[i],"}\n", sep="")) 
    cat(paste("Figure \\ref{class",i,"} \n", sep="")) 
    cat(paste("\\begin{figure}[H] \n", sep="")) 
    cat(paste("\\begin{center} \n", sep="")) 
    cat(paste("\\includegraphics[width=1\\textwidth,", 
      "height=.47\\textheight,keepaspectratio]{class",i,".pdf}\\caption{",titel[i],"}\n", sep="")) 

    cat(paste("\\label{class",i,"}" \n, sep="")) 
    cat(paste("\\end{center} \n",sep="")) 
    cat(paste("\\end{figure} \n",sep="")) 



    p <- ggplot(data[!is.na(data$F17),], aes_string(x=Fragen[i], y="..prop..", group = "1", fill="F17"))+ 
     geom_bar()+ 
     facet_grid(F17~.)+ 
     geom_text(aes(label = scales::percent(..prop..), 
       y= ..prop..), stat= "count", vjust = -.5, size=3) + 
     ylab("Prozent")+ 
     xlab(titel[i])+ 
     scale_fill_manual(name="Individuals", values=colorScheme)#+ 
     #theme_mine 


pdfnam<-paste("class",i,".pdf",sep="") #produce a plot for each class 
pdf(file=pdfnam,width=12, height = 4) 
#gridExtra::grid.arrange(p, q) 
print(p) 
dev.off() 
} 

@ 


\end{document} 

미리 감사!

+2

'pdf()'줄을 삭제하십시오. 이것은 플롯을 독립형 PDF로 저장하는 데 사용되며 보고서 내에 플롯을 포함하지 않기 위해 사용됩니다. – Gregor

+0

'\ label {abc}'는'\ ref {abc}'를 허용합니다. 그러나'\ label {figure/class }'(''주위에 공백이 있음)에'\ ref {} '(공백 포함)을 사용하고 있습니다. – Werner

+0

... [또한 \ centering' 대신에'\ begin {center}'를 사용해야 할 때?] (https://tex.stackexchange.com/q/23650/5764)'\ centering'을 사용해야합니다. . – Werner

답변

0

재현 가능한 스크립트를 사용하여 전달하려는 몇 가지 조언이 있습니다. 그것을 제공 주셔서 감사합니다, 그것은 많이 도움이됩니다.

보통 R 청크에 plot 또는 print(ggplot_object)이 있으면 knitr을 사용하여 그래프를 생성 할 수 있습니다. 귀하의 예에서는 플롯 객체를 생성하기 위해 begin{Figure}을 R 코드와 섞어보십시오. 당신은 그것을 사용할 필요가 없습니다. Knitr은 .Rnw 스크립트와 같은 폴더에있는 그림 경로 (기본값)를 가리키는 완전한 플롯 오브제를 만드는 도구를 제공합니다. 아래에 그 방법을 보여 드리고자합니다.

유일한 단점은 당신이 당신의 텍스 파일을 읽으려고하면 당신이 그 코드를 직접 (만든 것처럼, 그것은으로 잘 표현되지 것입니다 I은 ​​무슨 뜻인지 당신은 편집하여 텍스 파일, 모든 하나에있을 때 행하지만, 이것은 knitr에 대한 비판이 아니며 단지 매우 좋다.). 시도한 또 다른 선택은 그림을 한 폴더에 저장 한 다음 tex 명령으로로드하는 것입니다. 아래 예에서 스크립트를 사용하여 그림을 이런 식으로 포함시키는 방법을 보여줍니다. 그게 너에게 도움이되기를 바랍니다.

\documentclass{article} 

\usepackage{amsmath,amssymb,amstext} 
\usepackage{graphicx} 
\usepackage{geometry} 
\geometry{top=15mm, left=25mm, right=25mm, bottom=25mm,headsep=10mm,footskip=10mm} 
\usepackage{xcolor} 
\usepackage{float} 
\usepackage[T1]{fontenc} % Umlaute 
\usepackage[utf8]{inputenc} 
\inputencoding{latin1} 
\usepackage{hyperref} 
\begin{document} 
\parindent 0pt 

\title{title} 
\maketitle 

<<echo=FALSE, warning=FALSE, message=FALSE>>= 
library(ggplot2) 
library(reshape) 
library(knitr) 
library(doBy) 
library(dplyr) 


opts_chunk$set(fig.path='figure/graphic-', fig.align='center', fig.show='hold',fig.pos='!ht', 
      echo=FALSE,warning = FALSE) 

@ 

<<echo=FALSE, warning=FALSE, message=F>>= 

# data and other useful stuff 

data <- data.frame(F1 = c("A", "A", "B", "C"), # answers to question 1, ... 
        F2 = c("A", "B", "B", "C"), 
        F3 = c("A", "B", "C", "C"), 
        F17 = c("K", "L", "L", "M")) # K, L and M are a certain individual. L answered twice. 

# colour scheme: 
GH="#0085CA"; H="#DA291C"; BV="#44697D" 
colorScheme <- c(BV, H, GH) 

# individual theme for plots: 
theme_mine = theme(plot.background = element_rect(fill = "white"), 
       panel.background = element_rect(fill = "white", colour = "grey50"), 
       text=element_text(size=10, family="Trebuchet MS")) 

# a vector with the variable names from "data" (F1, F2, F3). 
Fragen <- c(paste0('F',seq(1:3), sep="")) 

# question title for labeling the plots: 
titel <- c("Q1", "Q2", "Q3", "Q17") 

@ 

First chunk uses the knitr output to place the figures, if you use ggplot don't 
forget to print your plot : \textbf{print(p)} otherwise it won't work . All your 
arguments are passed through chunk options. So where you tried to have them in the text, 
they are simply placed as other options to your chunk (see below). I have used 
the following options to reproduce your example. 
\begin{itemize} 
\item fig.width=9.6 
\item fig.height=6 
\item fig.pos='h', 
\item fig.cap="figa" 
\item fig.lp="figa" 
\item fig.align='center' 
\end{itemize} 

<<echo=FALSE, fig.width=9.6, fig.height=6, warning=FALSE, fig.pos='h', fig.cap="figa",fig.lp="figa", fig.align='center'>>= 

p <- ggplot(data, aes(x=F17))+ 
    geom_bar(fill = colorScheme)+ 
    xlab(titel[4])+ 
    #geom_text(aes(label = scales::percent(..prop..), 
    #   y= ..prop..), stat= "count", vjust = -.5, size=3) + 
    ylab("Absolut")+ 
    theme_bw() 
    #theme_mine # does not work properly yet. 
print(p) 

@ 




\section{individual plots} 

For individual plots we will use your script to generate the figure environment. 
To produce latex you need to pass the option 'asis'. 

<<generate_latex,echo=FALSE, warning=T, message=F, results='asis'>>= 
for(i in 1:3){ 
    cat(paste("\\subsection{",titel[i],"}\n", sep="")) 
    cat(paste("Figure \\ref{class",i,"} \n", sep="")) 
    cat(paste("\\begin{figure}[H] \n", sep="")) 
    cat(paste("\\begin{center} \n", sep="")) 
    cat(paste("\\includegraphics[width=1\\textwidth,", 
      "height=.47\\textheight,keepaspectratio]{class",i,".pdf}\\caption{",titel[i],"}\n", sep="")) 
    cat(paste("\\label{class",i,"} \n", sep="")) 
    cat(paste("\\end{center} \n",sep="")) 
    cat(paste("\\end{figure} \n",sep="")) 
} 
@ 
Now we need to save those figures. By default in knitr figures are saved in the \textit{figure} 
subfolder and path is set to \textit{figure/myfigure} in the includegraphics 
command in the tex file. 

<<plot,echo=FALSE, warning=T, message=F, fig.keep='all',fig.show='hide', results='hide'>>= 
for(i in 1:3){ 
    p <- ggplot(data[!is.na(data$F17),], aes_string(x=Fragen[i], y="..prop..", group = "1", fill="F17"))+ 
     geom_bar()+ 
     facet_grid(F17~.)+ 
     geom_text(aes(label = scales::percent(..prop..), 
       y= ..prop..), stat= "count", vjust = -.5, size=3) + 
     ylab("Prozent")+ 
     xlab(titel[i])+ 
     scale_fill_manual(name="Individuals", values=colorScheme)#+ 
     #theme_mine 
    print(p) 
} 
@ 
Now the other way to do it, as in sweave is just to save the plot where you 
want, this is the old sweave way, which I tend to use, I gave some explanation 
on how to arrange folders 
\href{https://stackoverflow.com/questions/46920038/how-to-get-figure-floated-surrounded-by-text-etc-in-r-markdown/46962362#46962362}{example script} 
In sweave you save those files using pdf() or png() or 
whatever device and set the graphics path to those figures using 
\textit{\\graphicspath{{/figure}}} in the preamble. If you want to set your 
graphics path to another folder you can set path using command like 
\textit{\\graphicspath{{../../figure}}}. This will set your path to the 
grandparent folder. 

Here I'm creating a directory, if existing, the code will still proceed with no 
warnings : \textit{dir.create(imagedir, showWarnings = FALSE)}. 

<<plot_manual,echo=FALSE, warning=T, message=F,results='hide'>>= 
imagedir<-file.path(getwd(), "figure") 
dir.create(imagedir, showWarnings = FALSE) # use show warning = FALSE 
pdfnam<-paste0(imagedir,"/class4.pdf") #produce a plot for each class 
pdf(file=pdfnam,width=8, height = 4) 
for(i in 4){ 
    p <- ggplot(data[!is.na(data$F17),], aes_string(x=Fragen[i], y="..prop..", group = "1", fill="F17"))+ 
     geom_bar()+ 
     facet_grid(F17~.)+ 
     geom_text(aes(label = scales::percent(..prop..), 
       y= ..prop..), stat= "count", vjust = -.5, size=3) + 
     ggtitle("manually saved plot")+ 
     ylab("Prozent")+ 
     xlab(titel[i])+ 
     scale_fill_manual(name="Individuals", values=colorScheme) 
    print(p) 
} 
dev.off() 
@ 
\subsection{section 4} 
This is Figure \ref{class4} 
\begin{figure}[H] 
\begin{center} 
    \includegraphics[width=1\textwidth,height=.47\textheight,keepaspectratio]{figure/class4.pdf} 
    \caption{Manually edited caption for figure 4} 
    \label{class4} 
    \end{center} 
\end{figure} 

\end{document} 
+0

매력처럼 작동합니다, 감사합니다! 한 번만 더 질문합니다. 첫 번째 솔루션 내에서 내 음모의 크기를 변경하고 싶다면'includegraphics [...] '내에서이 작업을 수행해야한다고 생각합니다. 불행히도 필자의 음모 만 조절할 수 있습니다. 즉, 텍스트의 크기가 조절됩니다 . 거기에 깔끔한 해결책이 있습니까? 또한 내가 원하는 곳에 플롯을 저장하는 두 번째 솔루션도 있습니다. 모든 플롯에서 for 루프를 사용하여 이것을 수행하려면 Latex Information을 for 루프에 넣어야합니다 (별도의 청크 내에서) 다시? 다시 한번 고마워요! – klamsi

+0

knitr에서는 [fig.width, fig.heigh] (https://yihui.name/knitr/options/) 옵션이 있지만 래스터 또는 PNG 이미지를 사용하는 경우주의하십시오. [SO 게시물] (https :// /stackoverflow.com/questions/32748235/how-to-remove-white-space-above-and-below-image-in-r-markdown/47429265#47429265).라텍스 출력의 경우 그래프를 pdf로 저장하는 것이 가장 좋습니다. 먼저 x11()과 같은 장치 창에서 플롯이 잘 보이는 지 확인하십시오. 그런 다음'dev.size()'를 사용하여 장치의 크기를 확인하십시오. 그런 다음 knitr에서 이러한 인수를 사용합니다. – Cedric

+0

두 번째 질문에 답하기 위해 숫자를 많이 생성해야한다면 아마 루프에서 라텍스 코드를 생성하는 것이 합리적 일 것입니다. 범주별로 보고서를 동적으로 생성하는 경우 (예 : 지역별 국가 별 그래프 ...). 나는 최종 보고서를 위해 그 많은 그래프를 생성하지는 않지만 종종 그것들을 \ subfigure environement에 포함시키는 것을 발견했다. 그래서 나는 많은 시간을 내 피규어를 다듬은 후 내 보고서 (니트르가 아닌)에서 직접 \ figure 환경을 생성합니다. – Cedric