Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass underscore in knitr R code

Tags:

r

knitr

I need to call a database that has underscores in the table names in an R chunk in knitr. There are a couple thousand table names, and changing the names would be a huge hassle. Something like:

<<classRun,fig=FALSE,print=FALSE,echo=FALSE>>=
getdat = function(nbr1,nbr2){
library(RODBC)
database.dsn1<-c("db")
database.user1<-c("username")
database.password1<-c("password")
channel<-odbcConnect(database.dsn1, database.user1, database.password1)
dat = sqlQuery(channel,paste("select * from table_",nbr1,"_",nbr2, sep=""))
}
@

<< results='asis', echo = FALSE>>=
dat = getdat(10,20)
print(dat)
@

I get the error that I am missing a $ ("Missing $ inserted") because of the underscore in "table_10_20". I have played around a lot with adding in '\$\', and '\$\', you name it. Also played around with cat(), and paste(), and single quotes, and double quotes. Any suggestions? Thanks in advance for your help. I am running Ubuntu 11.10, and calling knitr from RStudio with pdfLaTeX, if that matters.

like image 787
Jim Crozier Avatar asked Aug 28 '12 22:08

Jim Crozier


1 Answers

Chances are you have a column name with an underscore in it.

Recall that results='asis' just dumps all the output as-is into the tex document.

For example, this is a reproducible example of your problem:

% test.Rnw
\documentclass[a4paper]{article}                                                
\begin{document}                                                                
<<classRun, fig=FALSE, print=FALSE, echo=FALSE>>=                               
table_10_20 <- data.frame(col_1=1:10, col_2=runif(10))                          
@                                                                               

<<results='asis', echo=F>>=                                                     
print(table_10_20)                                                              
@                                                                               
\end{document}   

If I run this through knitr I get the "Missing $ inserted".

If I look at the .tex file that gets produced, I see:

% test.Rnw
\documentclass[a4paper]{article}                                                
.... lots of tex ....
\begin{document}

   col_1   col_2
1      1 0.69699
2      2 0.12988
3      3 0.19662
4      4 0.04299
5      5 0.08750
6      6 0.72969
7      7 0.19818
8      8 0.27855
9      9 0.81806
10    10 0.56135

\end{document}

See how the column names col_1 and col_2 are just dumped as-is into the file? Well, in LaTeX an underscore has a special meaning (subscript), which is only valid in maths mode, hence the LaTeX compiler tries to put the maths mode delimiters ($) around the word, giving your error.

In your case, you have a few options depending on what you want for your output.

  1. Use \begin{verbatim} with results='asis' to protect the underscores. This will dump your output into a verbatim environment.

    \begin{verbatim}
    <<results='asis', echo=F>>=       
    print(table_10_20)                              
    @      
    \end{verbatim}
    

    using verbatim

  2. Use results='markup': this is like a verbatim environment except sweave colours the output. By default it'll put a comment mark (##) in front of every line; to remove this use comment=NA. (You can't see too well how this pic is different from the above; it is the same except it has a grey background to distinguish it from the rest of the document. It's the same markup as when you use echo=T).

    <<results='markup', comment=NA, echo=F>>=      
    print(table_10_20)  
    @       
    

    using results=markup

  3. The above two simply print your table as-is in fixed with font. If you want a proper latex table, you can use a package like xtable, which can convert a data.frame (& similar) ino proper LaTeX (or HTML) markup. I think there are other packages that can do this too but for the moment they escape me. You use results='asis' here. (See the documentation for more details, you really can control every aspect of what gets printed in the table and how):

    <<results='asis', echo=F>>=      
    library(xtable)      
    print(xtable(table_10_20), include.rownames=FALSE)
    @                 
    

    using xtable

like image 108
mathematical.coffee Avatar answered Sep 19 '22 13:09

mathematical.coffee