美文网首页R
R 语言实战-Part 5-2

R 语言实战-Part 5-2

作者: 生物信息与育种 | 来源:发表于2019-04-28 21:45 被阅读6次

    R 语言实战(第二版)

    part 5-2 技能拓展


    ----------第21章创建包--------------------------

    #包是一套函数、文档和数据的合集,以一种标准的格式保存
    
    #1.测试npar包。进行非参组间比较
    pkg <- "npar_1.0.tar.gz"
    loc <- "http://www.statmethods.net/RiA"
    url <- paste(loc,pkg,sep = "/")
    download.file(url,pkg)
    install.packages(pkg,repos = NULL,type = "source")
    
    #假设检验
    library(npar)
    help("life")
    head(life)
    hist(life$hlef,col = "grey",breaks = 10) #检查正态性:因变量负偏
    library(ggplot2)
    ggplot(life,aes(region,hlef))+
      geom_point(size=3,color="darkgrey")+theme_bw()#检查方差齐性:方差不同
    #比较分组
    results <- oneway(hlef~region,life) #计算多重比较时,要考虑到alpha膨胀可能性,p.ajust来校正
    summary(results)#包括Kruskal-Wallis检验组间差异,总体统计量,成对分组比较(Wilcoxon秩和检验)
    plot(results,col="lightblue")
    
    
    #2.开发npar包
    ##1)计算统计量函数:oneway.R
    #开头注释#',会被roxygen2包生成包文档
    
    #' @title 非参组间比较
    #' 
    #' @description 
    #' \code{oneway} 计算非参组间比较,包括综合检验和事后成对组间比较
    #' 
    #' @details 
    #' 这个函数计算了一个综合Kruskal-Wallis检验,用于检验组别是否相等,接着使用Wilcoxon秩和检验来进行成对比较
    #' 
    #' @param formula
    #' @param data
    #' @param exact逻辑型变量
    #' @param sort逻辑型变量
    #' @param 用于调整多重比较的p值的方法,默认"holm"
    #' @export
    #' @return 
    #' \item{CALL}
    #' \item{data}
    #' \item{sumstats}
    #' \item{kw}
    #' \item{method}
    #' \item{wmc}
    #' \item{vnames}
    #' @author pjx<pjx@bgi.com>
    #' @examples 
    #' results <- oneway(helf~region,life)
    #' summary(results)
    #' plot(results,col="lightblue)
    
    oneway <- function(formula,data,exact=FALSE,sort=TRUE,
                       method=c("holm","hochberg","hommel","bonferroni","BH","BY","fdr","none")){
      #检查参数
      if(missing(formula) || class(formula) != "formula" || length(all.vars(formula)) != 2)
        stop("'formula' is missing or incorrect")
      method <- match.arg(method)
      
      #设定数据
      df <- model.frame(formula,data) #创建一个数据框,第一列为因变量,第二列为分组变量
      y <- df[[1]]
      g <- as.factor(df[[2]])
      vnames <- names(df)
      #重新排序
      if(sort) g <- reorder(g,y,FUN=median) #对分组变量g按照因变量y的中位数排序
      groups <- levels(g)
      k <- nlevels(g) #组的数目
      
      #总体统计量
      getstats <- function(x)(c(N=length(x),Median=median(x),MAD=mad(x)))
      sumstats <- t(aggregate(y,by=list(g),FUN=getstats)[2])
      rownames(sumstats) <- c("n","median","mad")
      colnames(sumstats) <- groups
      
      #统计检验
      kw <- kruskal.test(formula,data)
      wmc <- NULL
      for(i in 1:(k-1)){
        for (j in (i+1):k) {
          y1 <- y[g==groups[i]]
          y2 <- y[g==groups[j]]
          test <- wilcox.test(y1,y2,exact = exact)
          r <- data.frame(Group.1=group[i],Group.2=group[j],
                          W=test$statistic[[1]],p=test$p.value)
          wmc <- rbind(wmc,r)
        }
      }
      wmc$p <- p.adjust(wmc$p,method = method)
      
      #返回结果
      data <- data.frame(y,g)
      names(data) <- vnames
      results <- list(CALL=match.call(), #函数调用
                      data=data,sumstats=sumstats,kw=kw,
                      method=method,wmc=wmc,vnames=vnames)
      class(results) <- c("oneway","list") #设置这个列表的类
      return(results)
    }
    
    #尽管以上结果列表包含所有信息,但一般不会直接获取单个分量的信息。因此还需创建泛型函数如print/summary/plot等来表达更为具体和有意义的方法
    
    ##2)创建函数:print.R
    
    #' @title 
    #' 
    #' @description 
    #' \code{print.oneway}
    #' 
    #' @details 
    #' 
    #' @param x
    #' @param ...
    #' @method print oneway
    #' @export
    #' @return 
    #' @author 
    #' @example 
    #' results <- oneway(hlef~region,life)
    #' print(resluts)
    print.oneway <- function(x,...){
      #检查输入
      if(!inherits(x,"oneway")) #inherits函数确保有这个类
        stop("object must be of class 'oneway'")
      
      #打印头部
      cat("data:",x$vnames[1],"by",x$vnames[2],"\n\n")
      cat("multiple comparisons (Wilcoxon rank sum tests)\n")
      cat(paste("probability adjustment = ", x$method,"\n",sep = ""))
      
      #打印表格
      print(x$wmc,...)
    }
    
    
    ##3)汇总函数:summary.R
    summary(results)
    
    #' @title 
    #' 
    #' @description 
    #' \code{summary.oneway}
    #' nonparametric analysis.
    #' 
    #' @details 
    #' 
    #' @param object
    #' @param ...
    #' @method summary oneway
    #' @export
    #' @return 
    #' @author 
    #' @example 
    #' results <- oneway(hlef~region,life)
    #' summary(results)
    summrary.oneway <- function(object,...){
      if(!inherits(object,"oneway"))
        stop("object must be of class 'oneway'")
      
      if(!exists("digits")) digits <- 4L
      kw <- object$kw
      wmc <- object$wmc
      cat("data:",object$vnames[1],"on",object$vnames[2],"\n\n")
      
      #Kruskal-Wallis检验
      cat("omnibus test\n")
      cat(paste("Kruskal-Wallis chi-squared= ",
                round(kw$statistic,4),
                ",df=",round(kw$parameter,3),
                ",p-value=",format.pval(kw$p.value,digits = digits),
                "\n\n",sep = ""))
      
      #描述性统计量
      cat("Descriptive statistics\n")
      print(object$sumstats,...)
      
      #表格标记
      wmc$stars <- " "
      wmc$stars[wmc$p<0.1] <- "."
      wmc$stars[wmc$p<0.05] <- "*"
      wmc$stars[wmc$p<0.01] <- "**"
      wmc$stars[wmc$p<0.001] <- "***"
      names(wmc)[which(names(wmc)="stars")] <- " "
      
      #成分分组比较
      cat("\nmultiple comparisons (Wilcoxon rank sum tests)\n")
      cat(paste0("probability ajustment=",object$method,"\n"))
      print(wmc,...)
      cat("---\nsignif.codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1\n")
    }
    
    ##4)绘图函数:plot.R
    #注释同上,略
    plot.oneway <- function(x,...){
      if(!inherits(x,"oneway"))
        stop("object must be of class 'oneway'")
     #生成箱线图
       data <- x$data
      y <- data[,1]
      g <- data[,2]
      stats <- x$sumstats
      lbl <- paste("md=",stats[2,],"\nn=",stats[1,],sep = "")
      opar <- par(no.readonly = T)
      boxplot(y~g,...)
      #为图添加标记
      abline(h=median(y),lty=2,col="darkgrey")
      axis(3,at=1:length(lbl),labels = lbl,cex.axis=0.9)
      par(opar)
    }
    
    ##5)添加demo数据到包
    region <- c()
    state <- c()
    hlem <- c()
    hlef <- c()
    life <- data.frame(region,state,hlem,hlef)
    save(life,file = "life.rda")
    
    #添加数据也需要一个R代码文件life.R(注释文档后加一个NULL,再加一个空白行)
    #' @title 
    #' 
    #' @description 
    #' @docType  data
    #' @keywords datasets
    #' @name life
    #' @usage life
    #' @format 
    #' @source 
    NULL
    
    #R要求每一个包都有严格的结构化文档
    #LaTeX(标记语言和排版系统)编写文档,roxygen2包来简化文档创建过程
    
    #创建包步骤:
    #①安装工具:安装roxygen2包,Rtools.exe和MIKTeX工具(Windows)
    #②配置文件夹:R(oneway.R,print.R,summary.R,plot.R,npar.R,life.R),data(life.rda)
    #③生成文档:roxygenize("npar")
    #namespace命名空间控制函数的可视性
    #④建立包:system("R CMD build npar") 或system("Rcmd INSTALL --build npar")建立二进制包
    #⑤检查包(可选):system("R CMD check npar")发布到CRAN需无任何警告
    #⑥创建pdf手册(可选):system("R CMD Rd2pdf npar")
    #⑦本地安装包(可选):system("R CMD INSTALL npar")
    #⑧上传到CRAN(可选)
    

    ------------------第22章 创建动态报告--------------------------------------

    #四种类型的模板:R Markdown/ ODT/ DOCX/ LaTeX(出版级别文档,语法较复杂,学习曲线陡峭)
    
    #1.R markdown
    # ```{r echo=F,results='hide'}
    # ````
    #R代码块参数:
      # echo:T/F是否输出源码
      # results:asis/hide是否输出结果
      # warning:T/F是否输出警告
      # message:T/F是否输出参考信息
      # error:T/F是否输出错误信息
      # fig.width
      # fig.height
    
    #用Rstudio创建和处理R markdown
    #a. File——new File——R markdown 生成骨架文件进行编辑
    #b. 再点击Knit——render(to Html/PDF/Word) 
    
    #PS: 生成PDF文档需要安装MiKTeX(windows)
    
    
    #----------------第23章 使用lattice进行高级绘图---------------------------
    #特长:擅长网格图形,展示变量的分布或变量间的关系,每幅图代表一个变量或各个水平
    library(lattice)
    histogram(~height | voice.part,data=singer)
    #height是独立变量,voice.part是调节变量
    
    #y~x|A*B
    #x为主要变量,AB为调节变量。小写字母代表数值型变量,大写字母代表分类变量(因子)
    
    #lattice图类型及相应的函数:
    contourplot()
    levelplot()
    cloud()
    wireframe()
    barchart()
    bwplot()
    dotplot()
    histogram()
    densityplot()
    parallelplot()
    xyplot()
    splom()
    stripplot()
    
    #例子:
    library(lattice)
    attach(mtcars)
    gear <- factor(gear,levels = c(3,4,5),labels = c("3 gears","4 gears","5 gears"))
    cyl <- factor(cyl,levels = c(4,6,8),labels = c("4 cylinders","6 cylinders","8 cylinders"))
    head(mtcars)
    
    densityplot(~mpg)
    densityplot(~mpg|cyl)
    bwplot(cyl~mpg|cyl)
    xyplot(mpg~wt|cyl*gear)
    cloud(mpg~wt*qsec|cyl)
    dotplot(cyl~mpg|gear)
    splom(mtcars[c(1,3,4,5,6)])
    detach(mtcars)
    
    #图形参数:
    mygraph <- densityplot(~height|voice.part,data=singer);mygraph
    update(mygraph,col="red",pch=16,cex=0.8,jitter=0/05,lwd=2) #update函数调整图形对象
    
    #lattice绘图的一个强大特征是可以增加调节变量,通常调节变量是因子
    #若是连续变量,可先转换为shingle结构,再作为一个调节变量
    displacement <- equal.count(mtcars$disp,number=3,overlap=0) #将连续变量disp分成3个无重叠的间隔
    xyplot(mpg~wt|displacement,data=mtcars,
           layout=c(3,1),aspect = 1.5) #布局和纵横比(高/宽)
    
    #面板函数
    #每一个绘图函数都对应一个绘图面板panel.graph_function,如上图也可写成:
    xyplot(mpg~wt|displacement,data = mtcars,panel=panel.xyplot)
    #因此我们可将lattice默认的50多个默认函数组合成自定义函数,便类似于ggplot2的图层
    mypanel <- function(x,y){
      panel.xyplot(x,y,pch=19) #散点图
      panel.rug(x,y) #地毯图
      panel.grid(h=-1,v=-1) #网格线
      panel.lmline(x,y,col="red",lwd=1,lty=2) #回归曲线
    }
    xyplot(mpg~wt|displacement,data=mtcars,
           layout=c(3,1),aspect = 1.5,
           panel = mypanel)
    #例2
    mtcars$transmission <- factor(mtcars$am,levels = c(0,1),labels = c("automatic","manual"))
    panel.smoother <- function(x,y){
      panel.grid(h=-1,v=-1)
      panel.xyplot(x,y)
      panel.loess(x,y) #非参拟合曲线
      panel.abline(h=mean(y),lwd=2,lty=2,col="darkgrey") #水平参考线
    }
    xyplot(mpg~disp|transmission,data=mtcars,
           scales = list(cex=0.8,col="red"),
           panel=panel.smoother)
    
    #分组变量
    densityplot(~mpg,data=mtcars,auto.key = T, #图例放上方
                group=transmission) #添加分组变量每个水平的图
    #一个带有分组和调节变量以及自定义图例的例子:
    head(CO2)
    colors <- "darkgrey"
    symbols <- c(1:12)
    linetype <- c(1:3)
    #自定义图例
    key.species <- list(title="Plant",
                        space="right",
                        text=list(levels(CO2$Plant)),
                        points=list(symbols,col=colors))
    #Plant是分组变量,Type和Treatment是调节变量
    xyplot(uptake~conc|Type*Treatment,data=CO2,
           group=Plant,tpye="o",
           pch=symbols,col=colors,lty=linetype,
           key=key.species)
    
    show.settings(xyplot)
    
    show.settings() #查看图形参数默认设置(图形化)
    mysettings <- trellis.par.get() #得到图形默认设置
    names(mysettings)#查看图形参数列表成分
    mysettings$grid.pars
    mysettings$superpose.symbol #参数中具体某一成分的默认值
    mysettings$superpose.symbol$pch <- c(1:10) #改变默认值
    trellis.par.set(mysettings) #更改参数设置
    
    show.settings(mysettings) #查看改动
    
    #自定义图形条带:strip.custom
    #页面布局:split=c(1,2,1,2)
    

    -----------------------附录------------------------------

    #R GUI(如R Commander)与SAS和SPSS相比,不丰富和不成熟。
    #Shiny实现web互动
    
    #自定义启动环境:通过修改Rprofile.site(站点初始化文件)和.Rprofile(目录初始化文件),R启动时会执行其中代码
    #R启动步骤:加载R_HOME/etc/Rprofile.site文件——> 当前目录寻找.Rprofile,若没找到该文件,则到用户主目录HOME中去找
    
    Sys.getenv("R_HOME") #R_HOME环境变量位置
    Sys.getenv("HOME") #用户主目录HOME
    getwd() #当前工作目录
    
    #可以在这两个文件中放入两个特殊函数:.First函数(R会话开始时执行)和.Last函数(会话结束时执行)
    #Rprofile.site文件自定义示例:
    
    #常用选项设置
    options(papersize = "a4")
    options(editor = "notepad")
    options(tab.width=2)
    options(width = 130)
    options(digits = 4)
    options(stringsAsFactors = FALSE)
    options(show.signif.stars = FALSE)
    grDevices::windows.options(record=TRUE)
    
    #设置R交互提示符
    options(prompt = ">")
    options(continue = "+")
    
    #设置本地库路径
    .libPaths("D:/my_R-library") #在R目录外创建一个本地库
    
    #设置默认的CRAN镜像
    local({r <- getOption("repos")
      r["CRAN"] <- "http://cran.cae.edu/"
      options(repos=r)
    })
    
    #启动函数
    .First <- function(){
      library(lattice)
      library(ggplot2)
      source("E:/mydir/myfunctions.R")
      cat("\nWelcome at",date(),"\n")
    }
    
    #会话结束函数
    .Last <- function(){  #可执行某些清理安装,如保存历史记录、保存程序输出、保存数据等
      cat("\nGoodbye at",date(),"\n")
    }
    
    
    #更多方法:
    help("Startup")
    
    ##2.更新R
    #升级R自身较为复杂,主要是升级完后很多自定义选项和扩展包会丢失
    #手动将旧版R中包批量导入新R中的方法:
    oldip <- installed.packages()[,1];oldip #保存旧版已安装的包
    save(oldip,file="E:/installedPackages.Rdata") #保存已安装的包到非R目录下
    
    load("E:/installedPackages.Rdata") #打开新版R后,载入旧版R包
    newip <- installed.packages()[,1]
    for(i in setdiff(oldip,newip)){
      install.packages(i)
    }
    
    #但此方法只能安装CRAN上的包,如Bioconductor上的R包则只能重新安装
    source("http://biocondutor.org/biocLite.R")
    biocLite("globaltest")
    biocLite("Biobase")
    

    相关文章

      网友评论

        本文标题:R 语言实战-Part 5-2

        本文链接:https://www.haomeiwen.com/subject/oirsnqtx.html