rdaenvpart过程探索

2020-06-01 17:10:32 浏览数 (1)

最近赖江山老师发布了一个R包: 原创R包:rdaenvpart(层次分割获取RDA和CCA单解释变量的贡献) http://wap.sciencenet.cn/home.php?mod=space&uid=267448&do=blog&id=1199315

将Hierarchical Partitioning与rda(cca)相结合,可得到单个环境因子的解释度。 看了一下源代码,其核心的Hierarchical Partitioning用的是我之前介绍过的hier.part包。

以下对rdaenvpart的过程进行一下探索

代码语言:javascript复制
 1#主函数rdaenvpart
 2#其中包含了另外四个子函数
 3rdaenvpart=function (Y, X,type="RDA", pieplot = "tv")
 4{
 5#环境因子个数
 6    Env.num <- dim(X)[2]
 7#大于13个环境因子会报错
 8    if (Env.num > 13)
 9        stop("Number of variables must be < 13 for current implementation",call. = FALSE)
10    else {
11#allR2是一个子函数,其中又包含了2个子函数
12        gfs <- allR2(Y, X,type)
13#partition.rda是一个子函数,得到每个因子的解释度。
14        HP <- partition.rda(gfs, Env.num, var.names = names(data.frame(X)))
15#tv是展示每个解释变量占总变化量(total variation)的比例的饼图
16       if (pieplot=="tv") {
17           lbls<- c("unexplained",row.names(HP$I.perc)) 
18           pct <- round(c(1-sum(HP$IJ$I),HP$IJ$I)*100,1)
19           lbls <- paste(lbls, pct) # add percents to labels
20           lbls <- paste(lbls,"%",sep="") # ad % to labels
21#画图
22           pie(pct,labels = lbls, 
23                    main="individual % on total variation" )
24
25        }
26#tev是展示每个解释变量占总被解释变化量(total explained variation)的比例的饼图
27        if (pieplot=="tev") {
28           lbls<- row.names(HP$I.perc) 
29           pct <- round(HP$I.perc$I,1)
30           lbls <- paste(lbls, pct) # add percents to labels
31           lbls <- paste(lbls,"%",sep="") # ad % to labels
32#画图
33           pie(pct,labels = lbls, 
34                   main="individual % on total explained variation" )
35
36        }
37#计算R2及adjusted R2
38        if(type=="RDA")
39            rsq <- RsquareAdj(rda(Y~., data = X))
40         if(type=="CCA")
41             rsq <- RsquareAdj(cca(Y~., data = X))
42         list(R2=rsq$r.squared,gfs = gfs, IJ.R2 = HP$IJ, I.perc = HP$I.perc,adj.R2=rsq$adj.r.squared,IJ.adjR2=HP$I.perc*0.01*rsq$adj.r.squared)
43    }
44}

allR2,这里面还嵌套了两个函数,先往下拉看他们是干啥的。之后就知道allR2是得到环境因子的各种组合与OTU做cca或rda后得到的R2,并作为最后的gfs(拟合的优异度)输出。

代码语言:javascript复制
 1allR2=function (Y,X,type)
 2{
 3    Env.num <- dim(X)[2]
 4    n <- (2^Env.num) - 1
 5    combs <- hpmatrix(Env.num)
 6    gfs <- 0
 7
 8    for (i in 1:n) {
 9        current.comb <- as.vector(combs[i, ][combs[i, ] > 0])
10        combn <- paste(names(data.frame(X)[current.comb]),
11            "", collapse = "")
12        new.line <- R2current(Y, current.comb, X,type)
13        gfs <- c(gfs, new.line)
14    }
15    gfs
16}

hpmatrix,从环境因子中依次挑出来2,3,4,…n个因子,得到每种条件下可能的组合情况及组合数量。最后在汇总为所有环境因子组合的可能,并输出到allR2中的combs。

代码语言:javascript复制
1hpmatrix=function (n) 
2{   require(gtools)
3    x <- cbind(1:n, matrix(0, n, n - 1))
4    for (i in 2:n) {
5        nc <- dim(combinations(n, i, 1:n))[1]
6        x <- rbind(x, cbind(combinations(n, i, 1:n), matrix(0,nc, n - i)))
7    }
8x
9}

R2current,每种组合的条件下与OTU计算cca或rda,得到R2,并输出到allR2的new.line。

代码语言:javascript复制
1R2current=function(Y, current.comb, X,type)
2{require(vegan)
3    data <- data.frame(X[, current.comb])
4    if(type=="RDA")
5    gf <- RsquareAdj(rda(Y~., data = data))$r.squared
6    if(type=="CCA")
7    gf <- RsquareAdj(cca(Y~., data = data))$r.squared
8    gf
9}

到这为止主函数前12行完成。14行是另一个函数: partition.rda,用到了hier.part进行Hierarchical Partitioning。

代码语言:javascript复制
 1partition.rda=function (gfs, pcan, var.names = NULL)
 2{require(hier.part)
 3    if (pcan > 12)
 4        stop("Number of variables must be < 13 for current implementation",call. = FALSE)
 5    else if (pcan > 9)
 6        warning("rdaenvpart produces a rounding error if number of variables >9nSee documentation.",
 7            call. = FALSE)
 8    {
 9        n <- 2^pcan
10        theta <- gfs[1]
11        fin <- gfs[2:n]
12
13        len <- length(fin)
14        IJ <- vector("numeric", pcan * 2)
15        storage.mode(pcan) <- "integer"
16        storage.mode(len) <- "integer"
17        storage.mode(theta) <- "double"
18        storage.mode(fin) <- "double"
19        storage.mode(IJ) <- "double"
20        IJ <- .C("hierpart", pcan, len, theta, fin, IJ = IJ,
21            PACKAGE = "hier.part")$IJ
22        IJ <- array(IJ, dim = c(pcan, 2))
23        IJ <- data.frame(t(data.frame(t(IJ), row.names = c("I",
24            "J"))), row.names = var.names)
25        IJ.perc <- IJ * 100/sum(IJ)
26        I <- data.frame(I = IJ[, 1], row.names = var.names)
27        I.perc <- I * 100/sum(I)
28        IJ <- cbind(IJ, Total = IJ$I   IJ$J)
29        list(gfs = gfs, IJ = IJ, I.perc = I.perc)
30    }
31}

效果图,感觉画图这块还可以美化一下

另外还看到了两篇赖老师关于rda的文章: 关于RDA中每个环境因子解释率的说明 http://wap.sciencenet.cn/home.php?mod=space&uid=267448&do=blog&id=1186999

关于冗余分析(RDA)中环境因子共同解释部分出现负值的说明 http://wap.sciencenet.cn/home.php?mod=space&uid=267448&do=blog&id=1187530

END

0 人点赞