编辑中文的Rnw文件

如果您想出一本关于R或者Bioconductor的书,那么使用Sweave来写作无疑可以利用到latex中的诸多优势,同时还可以让系统自动检查和导出你的代码。那么如何使Rnw兼容中文体系统,尤其是简体中文呢?其实这并不难。

首先需要解决的是中文兼容问题。有几种选择,CJK, xeCJK,或者ctex,这决定于你的工作平台。如果你使用的是pdfLaTeX的话,可能需要CJK,如果是XeLaTex的话,后两者都是不错的选择。

这里我们选择XeLaTex做为工作平台。下面是模板(这里的模板只以一短篇文章示例,如果写书的话,使用书的模板。)有几点需要解释一下,

  • 因为这里是文章,所以使用的是ctexart,而不是ctexbook。
  • 文档需要以utf8格式保存
  • \DeclareTextCommandDefault{\nobreakspace}{\leavevmode\nobreak\ }是为了修复\nobreakspace命令错误。不同的系统不一定需要
  • 文中的代码段使用<<>>=至@标记起来。使用include=FALSE以及echo=FALSE分别来控制代码是用于输出代码还是输出图像,这样做的目的是为了让sweave自动生成的图像有图例控制。
  • \documentclass[UTF8]{ctexart}
    \usepackage{hyperref}
    \usepackage{url}
    \usepackage[numbers]{natbib}
    \usepackage{graphicx}
    \bibliographystyle{plainnat}
    \DeclareTextCommandDefault{\nobreakspace}{\leavevmode\nobreak\ }
     
    \begin{document} 
    \SweaveOpts{concordance=TRUE}
     
    \title{motifStack简介}
     
    \maketitle
     
    \tableofcontents
     
    \section{背景}
    序列图标是用于图形化显示氨基酸或者核酸模序的手段. 在Bioconductor中seqlogo\cite{Oliver}
    是生成序列图标的一个包,但是它不能用于氨基酸模序的显示. 
     
    motifStack包是为了方便人们在R中画出蛋白蛋,DNA,以及RNA序列图标.
    motifStack可以让人们自由地选择自己喜欢的字体和颜色来绘制图标. 
    与seqlogo不同的是,motifStack还可以同时在同一画布上绘制多个图标.
     
    \section{准备工作}
    motifStack需要GhostScript才能正常运行.在安装了GhostScript之后,你需要设置R中的R\_GSCMD环境变量.
    通常安装好的R会自动设置好这个变量.如果未能正常设置,请参考下面的例子设置即可.
     
    比如你使用的是Windows 32位操作系统,GhostScript安装在C:\textbackslash Program Files\textbackslash gs\textbackslash gs9.06\textbackslash bin, 那么你打开R后输入:
    \begin{scriptsize}
    Sys.setenv(R\_GSCMD="\textbackslash"C:\textbackslash\textbackslash Program Files\textbackslash\textbackslash gs\textbackslash\textbackslash gs9.06\textbackslash\textbackslash bin\textbackslash\textbackslash gswin32c.exe\textbackslash"")
    \end{scriptsize}
     
     
    \section{快速上手}
    \subsection{使用不同的字体及颜色绘制序列图标}
    用户可以自由地选择自己喜欢的字体和颜色绘制图标.
    \begin{scriptsize}
    <<DNAseqLogo,include=FALSE>>=
    library(motifStack)
    pcm <- read.table(file.path(find.package("motifStack"), "extdata", "bin_SOLEXA.pcm"))
    pcm <- pcm[,3:ncol(pcm)]
    rownames(pcm) <- c("A","C","G","T")
    motif <- pcm2pfm(pcm)
    #实例化pfm类
    motif <- new("pfm", mat=motif, name="bin_SOLEXA")
    plot(motif)
    #尝试使用不同的字体
    plot(motif, font="mono,Courier")
    #t尝试使用不同的颜色
    motif@color <- colorset(colorScheme='basepairing')
    plot(motif,font="Times")
    @
    \end{scriptsize}
    \begin{figure}[htb]
    \centering
    <<fig1,fig=TRUE,echo=FALSE>>=
    opar<-par(mfrow=c(3,1))
    motif@color<-colorset(colorScheme='auto')
    motif@name="bin_SOLEXA, font='Helvetica', color='auto'"
    plot(motif)
    motif@name="bin_SOLEXA, font='mono,Courier', color='auto'"
    plot(motif, font="mono,Courier")
    motif@color <- colorset(colorScheme='basepairing')
    motif@name="bin_SOLEXA, font='mono,Courier', color='basepairing'"
    plot(motif,font="Times")
    par<-opar
    @
    \caption{DNA序列图标}
    \label{fig:font}
    \end{figure}
     
    \subsection{绘制氨基酸序列图标}
    实际上,motifStack允许用户使用任何字符做为图标中的字母,这是由pfm类实例的mat行号决定.
    所以它可以被用来绘制氨基酸序列图标.
    \begin{scriptsize}
    <<AAseqLogo,include=FALSE>>=
    library(motifStack)
    protein<-read.table(file.path(find.package("motifStack"),"extdata","cap.txt"))
    protein<-t(protein[,1:20])
    motif<-pcm2pfm(protein)
    motif<-new("pfm", mat=motif, name="CAP", 
                color=colorset(alphabet="AA",colorScheme="chemistry"))
    plot(motif)
    @
    \end{scriptsize}
    \begin{figure}[htb]
    \centering
    <<fig2,fig=TRUE,echo=FALSE>>=
    plot(motif)
    @
    \caption{氨基酸序列图标}
    \label{fig:protein}
    \end{figure}
     
    \subsection{绘制图标堆}
    motifStack可以在同一画布上绘制多个图标. 如果图标需要对齐绘制的话,需要事先对模序进行对齐工作.
    这一步可以由整合了STAMP\cite{Mahony2007}的MotIV\cite{Eloi2010}::motifMatch来完成. 
    对齐以后就可以使用plotMotifLogoStack()以及plotMotifLogoStackWithTree()函数来绘制图标堆以及左侧带有进化树的图标堆了.
     
    \begin{scriptsize}
    <<seqLogoStack,include=FALSE>>=
    library(motifStack)
    library("MotIV")
    #####读入数据库及打分表#####
    jaspar <- MotIV::readPWMfile(file.path(find.package("MotIV"), "extdata", "jaspar2010.txt"))
    jaspar.scores <- MotIV::readDBScores(file.path(find.package("MotIV"), "extdata", "jaspar2010_PCC_SWU.scores"))
    #####输入#####
    pcms<-readPCM(file.path(find.package("motifStack"), "extdata"),"pcm$")
    pcms<-lapply(pcms,function(.ele){.ele<-.ele[,3:ncol(.ele)];rownames(.ele)<-c("A","C","G","T");.ele})
    motifs<-lapply(pcms,pcm2pfm)
     
    #####分析#####
    foxa1.analysis.jaspar<-MotIV::motifMatch(inputPWM=motifs,
                                             align="SWU",cc="PCC",
                                             database=jaspar, DBscores=jaspar.scores,top=5)
    #####聚类分析#####
    d <- MotIV::motifDistances(getPWM(foxa1.analysis.jaspar))
    hc <- MotIV::motifHclust(d)
     
    ##对模序进行重排
    motifs<-motifs[hc$order]
    motifs<-lapply(names(motifs), function(.ele, motifs){new("pfm",mat=motifs[[.ele]], name=.ele)},motifs)
    ##对齐
    motifs<-DNAmotifAlignment(motifs)
    ##绘制图形
    plotMotifLogoStack(motifs, ncex=1.0)
    plotMotifLogoStackWithTree(motifs, hc=hc)
    @
    \end{scriptsize}
    \begin{figure}[htb]
    \centering
    <<fig3,fig=TRUE,echo=FALSE>>=
    plotMotifLogoStack(motifs, ncex=1.0)
    @
    \caption{序列图标堆}
    \label{fig:logostack}
    \end{figure}
    \begin{figure}[htb]
    \centering
    <<fig4,fig=TRUE,echo=FALSE>>=
    plotMotifLogoStackWithTree(motifs, hc=hc)
    @
    \caption{带有关系树的图标堆}
    \label{fig:treestack}
    \end{figure}
     
    \subsection{绘制环形风格的图标堆}
    当图标过多,无法使用上面的函数绘制的时候,可以使用plotMotifStackWithRadialPhylog()函数绘制环形风格图标堆.
     
    \begin{scriptsize}
    <<radialLogoStack,include=FALSE>>=
    library("MotifDb")
    library("MotIV")
    library("motifStack")
    matrix.fly <- query(MotifDb, "Dmelanogaster")
    motifs <- as.list(matrix.fly)
    motifs <- motifs[grepl("Dmelanogaster\\-FlyFactorSurvey\\-", names(motifs))]
    names(motifs) <- gsub("Dmelanogaster_FlyFactorSurvey_", "", 
                          gsub("_FBgn\\d+$", "", 
                                gsub("[^a-zA-Z0-9]","_", 
                                     gsub("(_\\d+)+$", "", names(motifs)))))
    motifs <- motifs[unique(names(motifs))]
    pfms <- sample(motifs, 50)
    jaspar <- MotIV::readPWMfile(file.path(find.package("MotIV"), "extdata", "jaspar2010.txt"))
    jaspar.scores <- MotIV::readDBScores(file.path(find.package("MotIV"), "extdata", "jaspar2010_PCC_SWU.scores"))
    ffs.analysis.jaspar<-MotIV::motifMatch(inputPWM=pfms,align="SWU",
                                           cc="PCC",database=jaspar, 
                                           DBscores=jaspar.scores,top=5)
    d <- MotIV::motifDistances(getPWM(ffs.analysis.jaspar))
    hc <- MotIV::motifHclust(d)
    phylog <- hclust2phylog(hc)
    leaves <- names(phylog$leaves)
    pfms <- pfms[leaves]
    pfms <- lapply(names(pfms), function(.ele, pfms){new("pfm",mat=pfms[[.ele]], name=.ele)},pfms)
    pfms <- DNAmotifAlignment(pfms, minimalConsensus=3)
    library(RColorBrewer)
    color <- brewer.pal(12, "Set3")
    @
    > plotMotifStackWithRadialPhylog(phylog, pfms, circle=0.9, cleaves = 0.5, clabel.leaves = 0.7, 
                                     col.bg=rep(color, each=5), col.leaves=rep(color, each=5))
    \end{scriptsize}
    \begin{figure}[htb]
    \centering
    <<fig5,fig=TRUE,echo=FALSE>>=
    plotMotifStackWithRadialPhylog(phylog, pfms, circle=0.3, cleaves = 0.2, clabel.leaves = 0.6, 
                                     col.bg=rep(color, each=5), col.leaves=rep(color, each=5))
    @
    \caption{sequence logo stack in radial style}
    \label{fig:treestack}
    \end{figure}
     
    \section{References}
    \begin{thebibliography}{99}
    \bibitem[Oliver Bembom ()]{Oliver} seqLogo: Sequence logos for DNA sequence alignments. R package version 1.22.0. 
    \bibitem[Eloi et al. (2010)]{Eloi2010} MotIV: Motif Identification and Validation. Eloi Mercier and Raphael Gottardo (2010). R package version 1.10.0.
    \bibitem[Mahony et al. (2007)]{Mahony2007} STAMP: a web tool for exploring DNA-binding motif similarities. Mahony S, Benos PV, Nucleic Acids Res. 2007, 35(Web Server issue): W253-W258.
    \end{thebibliography}
     
    \section{Session Info}
    <<>>=
    sessionInfo()
    @
     
     
    \end{document}

    在完成了写作之后,我们要使用Sweave来转换Rnw文件至tex文件。

    R CMD Sweave test.Rnw --encoding=utf8

    如果想把代码变换成彩色的,可以使用SweaveListingUtils包来重定义环境,具体操作参见它的说明文档

    原本R提供了命令

    R CMD xelatex test.tex

    为我们选择。如果我们安装了tex的图形化工作界面的话,使用图形化工作界面读入tex文件并转换成PDF也是不错的选择。
    来看一眼生成的文件吧:

    最后,我们希望把文中所有的代码段全部都提取出来,放在一个单独的附件里。
    我们需要在R中运行

    > Stangle("test.Rnw", output="testCodeOutput.R",encoding="utf8")

    于是我们得到:

    ### R code from vignette source 'testRStudio.Rnw'
    ### Encoding: UTF-8
     
    ###################################################
    ### code chunk number 1: DNAseqLogo
    ###################################################
    library(motifStack)
    pcm <- read.table(file.path(find.package("motifStack"), "extdata", "bin_SOLEXA.pcm"))
    pcm <- pcm[,3:ncol(pcm)]
    rownames(pcm) <- c("A","C","G","T")
    motif <- pcm2pfm(pcm)
    #实例化pfm类
    motif <- new("pfm", mat=motif, name="bin_SOLEXA")
    plot(motif)
    #尝试使用不同的字体
    plot(motif, font="mono,Courier")
    #t尝试使用不同的颜色
    motif@color <- colorset(colorScheme='basepairing')
    plot(motif,font="Times")
     
     
    ###################################################
    ### code chunk number 2: fig1
    ###################################################
    opar<-par(mfrow=c(3,1))
    motif@color<-colorset(colorScheme='auto')
    motif@name="bin_SOLEXA, font='Helvetica', color='auto'"
    plot(motif)
    motif@name="bin_SOLEXA, font='mono,Courier', color='auto'"
    plot(motif, font="mono,Courier")
    motif@color <- colorset(colorScheme='basepairing')
    motif@name="bin_SOLEXA, font='mono,Courier', color='basepairing'"
    plot(motif,font="Times")
    par<-opar
     
     
    ###################################################
    ### code chunk number 3: AAseqLogo
    ###################################################
    library(motifStack)
    protein<-read.table(file.path(find.package("motifStack"),"extdata","cap.txt"))
    protein<-t(protein[,1:20])
    motif<-pcm2pfm(protein)
    motif<-new("pfm", mat=motif, name="CAP", 
                color=colorset(alphabet="AA",colorScheme="chemistry"))
    plot(motif)
     
     
    ###################################################
    ### code chunk number 4: fig2
    ###################################################
    plot(motif)
     
     
    ###################################################
    ### code chunk number 5: seqLogoStack
    ###################################################
    library(motifStack)
    library("MotIV")
    #####读入数据库及打分表#####
    jaspar <- MotIV::readPWMfile(file.path(find.package("MotIV"), "extdata", "jaspar2010.txt"))
    jaspar.scores <- MotIV::readDBScores(file.path(find.package("MotIV"), "extdata", "jaspar2010_PCC_SWU.scores"))
    #####输入#####
    pcms<-readPCM(file.path(find.package("motifStack"), "extdata"),"pcm$")
    pcms<-lapply(pcms,function(.ele){.ele<-.ele[,3:ncol(.ele)];rownames(.ele)<-c("A","C","G","T");.ele})
    motifs<-lapply(pcms,pcm2pfm)
     
    #####分析#####
    foxa1.analysis.jaspar<-MotIV::motifMatch(inputPWM=motifs,
                                             align="SWU",cc="PCC",
                                             database=jaspar, DBscores=jaspar.scores,top=5)
    #####聚类分析#####
    d <- MotIV::motifDistances(getPWM(foxa1.analysis.jaspar))
    hc <- MotIV::motifHclust(d)
     
    ##对模序进行重排
    motifs<-motifs[hc$order]
    motifs<-lapply(names(motifs), function(.ele, motifs){new("pfm",mat=motifs[[.ele]], name=.ele)},motifs)
    ##对齐
    motifs<-DNAmotifAlignment(motifs)
    ##绘制图形
    plotMotifLogoStack(motifs, ncex=1.0)
    plotMotifLogoStackWithTree(motifs, hc=hc)
     
     
    ###################################################
    ### code chunk number 6: fig3
    ###################################################
    plotMotifLogoStack(motifs, ncex=1.0)
     
     
    ###################################################
    ### code chunk number 7: fig4
    ###################################################
    plotMotifLogoStackWithTree(motifs, hc=hc)
     
     
    ###################################################
    ### code chunk number 8: radialLogoStack
    ###################################################
    library("MotifDb")
    library("MotIV")
    library("motifStack")
    matrix.fly <- query(MotifDb, "Dmelanogaster")
    motifs <- as.list(matrix.fly)
    motifs <- motifs[grepl("Dmelanogaster\\-FlyFactorSurvey\\-", names(motifs))]
    names(motifs) <- gsub("Dmelanogaster_FlyFactorSurvey_", "", 
                          gsub("_FBgn\\d+$", "", 
                                gsub("[^a-zA-Z0-9]","_", 
                                     gsub("(_\\d+)+$", "", names(motifs)))))
    motifs <- motifs[unique(names(motifs))]
    pfms <- sample(motifs, 50)
    jaspar <- MotIV::readPWMfile(file.path(find.package("MotIV"), "extdata", "jaspar2010.txt"))
    jaspar.scores <- MotIV::readDBScores(file.path(find.package("MotIV"), "extdata", "jaspar2010_PCC_SWU.scores"))
    ffs.analysis.jaspar<-MotIV::motifMatch(inputPWM=pfms,align="SWU",
                                           cc="PCC",database=jaspar, 
                                           DBscores=jaspar.scores,top=5)
    d <- MotIV::motifDistances(getPWM(ffs.analysis.jaspar))
    hc <- MotIV::motifHclust(d)
    phylog <- hclust2phylog(hc)
    leaves <- names(phylog$leaves)
    pfms <- pfms[leaves]
    pfms <- lapply(names(pfms), function(.ele, pfms){new("pfm",mat=pfms[[.ele]], name=.ele)},pfms)
    pfms <- DNAmotifAlignment(pfms, minimalConsensus=3)
    library(RColorBrewer)
    color <- brewer.pal(12, "Set3")
     
     
    ###################################################
    ### code chunk number 9: fig5
    ###################################################
    plotMotifStackWithRadialPhylog(phylog, pfms, circle=0.3, cleaves = 0.2, clabel.leaves = 0.6, 
                                     col.bg=rep(color, each=5), col.leaves=rep(color, each=5))
     
     
    ###################################################
    ### code chunk number 10: testRStudio.Rnw:202-203
    ###################################################
    sessionInfo()

2 thoughts on “编辑中文的Rnw文件

  1. 多谢分享,这段时间正在从MS WORD往latex转型,你的文章正好解决了我用latex写中文文档的问题。利用Rknitr/Sweave + latex + pandoc写作的确极大地方便了我们的写作。不用再烦恼MS WORD中复制粘贴图片了,让工作的可重复性变得更容易。

发表评论

电子邮件地址不会被公开。 必填项已用*标注