O'Hara和Kotze的论文(《生态学与进化的方法》 1:18-122)并不是一个很好的讨论起点。我最严重的担心是摘要中第4点的主张:
我们发现,除之外,这些转换的效果都很差。。..拟泊松模型和负二项式模型... [显示]偏差很小。
λθλ
λ
以下R代码说明了这一点:
x <- rnbinom(10000, 0.5, mu=2)
## NB: Above, this 'mu' was our lambda. Confusing, is'nt it?
log(mean(x+1))
[1] 1.09631
log(2+1) ## Check that this is about right
[1] 1.098612
mean(log(x+1))
[1] 0.7317908
或尝试
log(mean(x+.5))
[1] 0.9135269
mean(log(x+.5))
[1] 0.3270837
参数估计的规模非常重要!
λ
请注意,标准诊断在log(x + c)的范围内效果更好。c的选择可能没有太大关系;通常0.5或1.0才有意义。这也是研究Box-Cox转换或Box-Cox的Yeo-Johnson变体的更好的起点。[Yeo,I.和Johnson,R.(2000)]。进一步参见R的汽车包装中的powerTransform()帮助页面。R的gamlss包使得可以拟合负二项式类型I(常见变体)或II,或其他建模离散度和均值的其他分布,且幂变换链接为0(=对数,即,对数链接)或更大。拟合可能并不总是收敛。
示例:死亡人数与基本伤害
数据是针对到达美国大陆的命名大西洋飓风的。最新版本的R的DAAG软件包提供了数据(名称为hurricNamed)。数据的帮助页面包含详细信息。
该图将使用鲁棒线性模型拟合获得的拟合线与通过将对数链接的负二项式拟合转换为用于图上y轴的log(count + 1)标度获得的曲线进行比较。(请注意,必须使用类似于log(count + c)的比例,正值为c,以在同一张图中显示点和负二项式拟合的拟合“线”。)请注意,存在较大的偏差对数刻度上的负二项式拟合很明显。如果人们假设计数的负二项式分布,则稳健的线性模型拟合在此比例上的偏差要小得多。在经典法线理论假设下,线性模型拟合将是无偏的。当我第一次创建上面的图表时,我发现偏差令人惊讶!曲线会更好地拟合数据,但差异在通常的统计变异性标准范围内。健壮的线性模型拟合对于量表低端的计数效果不佳。
注意---使用RNA-Seq数据的研究:比较两种样式的模型对于分析来自基因表达实验的计数数据非常重要。以下论文将使用log(count + 1)的健壮线性模型与负二项式拟合(如在Bioconductor包edgeR中)进行了比较。在最初考虑的RNA-Seq应用中,大多数计数都足够大,以至于适当加权的对数线性模型拟合效果非常好。
Law,CW,Chen,Y,Shi,W,Smyth,GK(2014)。Voom:精确的权重可为RNA-seq读数计数解锁线性模型分析工具。Genome Biology 15,R29。http://genomebiology.com/2014/15/2/R29
NB还有最近的论文:
Schurch NJ,Schofield P,GierlińskiM,Cole C,Sherstnev A,Singh V,Wrobel N,Gharbi K,Simpson GG,Owen-Hughes T,Blaxter M,Barton GJ(2016)。RNA-seq实验需要多少个生物复制品,您应该使用哪种差异表达工具?RNA
http://www.rnajournal.org/cgi/doi/10.1261/rna.053959.115
有趣的是,使用线性模型拟合LIMMA包(如磨边机,从WEHI组)站起来,非常好(中流露出的偏见没有证据的意义上),相对于许多重复的结果,因为重复的号码是减少。
上图的R代码:
library(latticeExtra, quietly=TRUE)
hurricNamed <- DAAG::hurricNamed
ytxt <- c(0, 1, 3, 10, 30, 100, 300, 1000)
xtxt <- c(1,10, 100, 1000, 10000, 100000, 1000000 )
funy <- function(y)log(y+1)
gph <- xyplot(funy(deaths) ~ log(BaseDam2014), groups= mf, data=hurricNamed,
scales=list(y=list(at=funy(ytxt), labels=paste(ytxt)),
x=list(at=log(xtxt), labels=paste(xtxt))),
xlab = "Base Damage (millions of 2014 US$); log transformed scale",
ylab="Deaths; log transformed; offset=1",
auto.key=list(columns=2),
par.settings=simpleTheme(col=c("red","blue"), pch=16))
gph2 <- gph + layer(panel.text(x[c(13,84)], y[c(13,84)],
labels=hurricNamed[c(13,84), "Name"], pos=3,
col="gray30", cex=0.8),
panel.text(x[c(13,84)], y[c(13,84)],
labels=hurricNamed[c(13,84), "Year"], pos=1,
col="gray30", cex=0.8))
ab <- coef(MASS::rlm(funy(deaths) ~ log(BaseDam2014), data=hurricNamed))
gph3 <- gph2+layer(panel.abline(ab[1], b=ab[2], col="gray30", alpha=0.4))
## 100 points that are evenly spread on a log(BaseDam2014) scale
x <- with(hurricNamed, pretty(log(BaseDam2014),100))
df <- data.frame(BaseDam2014=exp(x[x>0]))
hurr.nb <- MASS::glm.nb(deaths~log(BaseDam2014), data=hurricNamed[-c(13,84),])
df[,'hatnb'] <- funy(predict(hurr.nb, newdata=df, type='response'))
gph3 + latticeExtra::layer(data=df,
panel.lines(log(BaseDam2014), hatnb, lwd=2, lty=2,
alpha=0.5, col="gray30"))