如何在 clmm 之后使用 dotplot
how to use dotplot after clmm
我试图在 clmm
之后绘制随机效应,但我收到错误消息:"Error in sort.list(y):'x' must be atomic for `sort.list' Have you called 'sort' an a list?" 以下代码代表我的实际代码。
library(ordinal)
library(lattice)
###I am using the wine data in the ordinal package
d<-data.frame(wine)
result<-clmm(rating~1+temp+contact+(1+temp|judge), data=d)
###In my actual codes, I put "as.ordered(rating)" instead of "rating".
然后,我正在尝试绘制温度的随机影响并判断:
dotplot(ranef(result, condVar=TRUE))
然后,出现错误信息:"Error in sort.list(y):'x' must be atomic for `sort.list' Have you called 'sort' on a list?"
我最好的猜测是评级是按照 clmm
下的命令实施的,鉴于错误消息,这对我来说似乎是有道理的。然而,猜测是高度推测性的,我不知道如何处理这种情况。 具体来说,我想绘制的是temp和judge(拦截)及其CI的随机效应。请参考我使用以下代码生成的以下图
result2<-lmer(as.numeric(rating)~1+temp+contact+(1+temp|judge), data=d)
dotplot(ranef(result2, condVar=TRUE))
如果您能就如何避免使用 clmm
阻止我使用上面的代码使用 dotplot
的看似冲突的情况提出任何意见或建议,我们将不胜感激。
dotplot
不知道如何处理 ranef(clmm(...))
的结果,因为它没有与此结果相关的方法。
'simple' 答案是你可以设置结果的 class (与 ranef(lm34::lmer(...))
提供的 class 相同)来规避这个:
r1 <- ranef(result, condVar=TRUE)
class(r1)="ranef.mer"
dotplot(r1)
这会得到一个点图,但没有条件标准误差条。
要绘制条件误差线还需要更多努力。问题是 lme4::dotplot.ranef.mer
试图在名为 postVar
的属性中查找错误,而 clmm 在名为 condVar
的不同格式的属性中提供错误。幸运的是,编辑 dotplot.ranef.mer
来处理 clmm 对象相对简单。我们可以通过在函数中添加一行来做到这一点:
if (!is.null(cv <- attr(xt, "condVar"))) se <- as.vector(unlist(cv))
然后我们可以使用
得到图
result<-clmm(rating~1+temp+contact+(1+temp|judge), data=d)
r1 <- ranef(result, condVar=TRUE)
dp(r1, scales = list(x = list(relation = 'free')))
下面是绘制此图的整个函数。这是 dotplot.ranef.mer
的逐字副本,添加了上面提到的一行
dp <- function (x, data, main = TRUE, ...)
{
prepanel.ci <- function(x, y, se, subscripts, ...) {
if (is.null(se))
return(list())
x <- as.numeric(x)
hw <- 1.96 * as.numeric(se[subscripts])
list(xlim = range(x - hw, x + hw, finite = TRUE))
}
panel.ci <- function(x, y, se, subscripts, pch = 16, horizontal = TRUE,
col = dot.symbol$col, lty = dot.line$lty, lwd = dot.line$lwd,
col.line = dot.line$col, levels.fos = unique(y), groups = NULL,
...) {
x <- as.numeric(x)
y <- as.numeric(y)
dot.line <- trellis.par.get("dot.line")
dot.symbol <- trellis.par.get("dot.symbol")
sup.symbol <- trellis.par.get("superpose.symbol")
panel.abline(h = levels.fos, col = col.line, lty = lty,
lwd = lwd)
panel.abline(v = 0, col = col.line, lty = lty, lwd = lwd)
if (!is.null(se)) {
se <- as.numeric(se[subscripts])
panel.segments(x - 1.96 * se, y, x + 1.96 * se, y,
col = "black")
}
panel.xyplot(x, y, pch = pch, ...)
}
f <- function(nx, ...) {
xt <- x[[nx]]
ss <- stack(xt)
mtit <- if (main)
nx
ss$ind <- factor(as.character(ss$ind), levels = colnames(xt))
ss$.nn <- rep.int(reorder(factor(rownames(xt)), xt[[1]],
FUN = mean, sort = sort), ncol(xt))
se <- NULL
if (!is.null(pv <- attr(xt, "postVar")))
se <- unlist(lapply(1:(dim(pv)[1]), function(i) sqrt(pv[i, i, ])))
#############################################################
# Next line is the inseerted line to deal with clmm objects
#############################################################
if (!is.null(cv <- attr(xt, "condVar"))) se <- as.vector(unlist(cv))
dotplot(.nn ~ values | ind, ss, se = se, prepanel = prepanel.ci,
panel = panel.ci, xlab = NULL, main = mtit, ...)
}
setNames(lapply(names(x), f, ...), names(x))
}
我开始尝试破解 lme4:::dotplot.ranef.mer
的内部结构,但事实证明使用 reshape2::melt
和 ggplot2
更容易做到这一点。抱歉,如果您非常喜欢 lattice
...
顺便请注意,从技术上讲,这些不是 "confidence intervals"(因为预测的条件模式在技术、常客意义上不是 "estimates")...
将条件模式的点估计和 SE 重新排列成有用的形状:
library(reshape2)
melt.ranef.clmm <- function(re,cv) {
reList <- lapply(re,
function(x) {
x$id <- reorder(factor(rownames(x)),x[,1])
return(melt(x,id.var="id"))
})
cvList <- lapply(cv,melt,id.var=NULL,value.name="se")
mm <- Map(cbind,reList,cvList)
return(mm)
}
将此应用于模型(m1
是拟合模型):
ss <- melt.ranef.clmm(ranef(m1),condVar(m1))
剧情:
library(ggplot2); theme_set(theme_bw())
ggplot(ss[[1]],aes(value,id))+
geom_errorbarh(aes(xmin=value-1.96*se,xmax=value+1.96*se),
height=0)+
ggtitle(names(ss)[1])+
geom_point(colour="blue")+
facet_wrap(~variable,scale="free_x")
我试图在 clmm
之后绘制随机效应,但我收到错误消息:"Error in sort.list(y):'x' must be atomic for `sort.list' Have you called 'sort' an a list?" 以下代码代表我的实际代码。
library(ordinal)
library(lattice)
###I am using the wine data in the ordinal package
d<-data.frame(wine)
result<-clmm(rating~1+temp+contact+(1+temp|judge), data=d)
###In my actual codes, I put "as.ordered(rating)" instead of "rating".
然后,我正在尝试绘制温度的随机影响并判断:
dotplot(ranef(result, condVar=TRUE))
然后,出现错误信息:"Error in sort.list(y):'x' must be atomic for `sort.list' Have you called 'sort' on a list?"
我最好的猜测是评级是按照 clmm
下的命令实施的,鉴于错误消息,这对我来说似乎是有道理的。然而,猜测是高度推测性的,我不知道如何处理这种情况。 具体来说,我想绘制的是temp和judge(拦截)及其CI的随机效应。请参考我使用以下代码生成的以下图
result2<-lmer(as.numeric(rating)~1+temp+contact+(1+temp|judge), data=d)
dotplot(ranef(result2, condVar=TRUE))
如果您能就如何避免使用 clmm
阻止我使用上面的代码使用 dotplot
的看似冲突的情况提出任何意见或建议,我们将不胜感激。
dotplot
不知道如何处理 ranef(clmm(...))
的结果,因为它没有与此结果相关的方法。
'simple' 答案是你可以设置结果的 class (与 ranef(lm34::lmer(...))
提供的 class 相同)来规避这个:
r1 <- ranef(result, condVar=TRUE)
class(r1)="ranef.mer"
dotplot(r1)
这会得到一个点图,但没有条件标准误差条。
要绘制条件误差线还需要更多努力。问题是 lme4::dotplot.ranef.mer
试图在名为 postVar
的属性中查找错误,而 clmm 在名为 condVar
的不同格式的属性中提供错误。幸运的是,编辑 dotplot.ranef.mer
来处理 clmm 对象相对简单。我们可以通过在函数中添加一行来做到这一点:
if (!is.null(cv <- attr(xt, "condVar"))) se <- as.vector(unlist(cv))
然后我们可以使用
得到图result<-clmm(rating~1+temp+contact+(1+temp|judge), data=d)
r1 <- ranef(result, condVar=TRUE)
dp(r1, scales = list(x = list(relation = 'free')))
下面是绘制此图的整个函数。这是 dotplot.ranef.mer
的逐字副本,添加了上面提到的一行
dp <- function (x, data, main = TRUE, ...)
{
prepanel.ci <- function(x, y, se, subscripts, ...) {
if (is.null(se))
return(list())
x <- as.numeric(x)
hw <- 1.96 * as.numeric(se[subscripts])
list(xlim = range(x - hw, x + hw, finite = TRUE))
}
panel.ci <- function(x, y, se, subscripts, pch = 16, horizontal = TRUE,
col = dot.symbol$col, lty = dot.line$lty, lwd = dot.line$lwd,
col.line = dot.line$col, levels.fos = unique(y), groups = NULL,
...) {
x <- as.numeric(x)
y <- as.numeric(y)
dot.line <- trellis.par.get("dot.line")
dot.symbol <- trellis.par.get("dot.symbol")
sup.symbol <- trellis.par.get("superpose.symbol")
panel.abline(h = levels.fos, col = col.line, lty = lty,
lwd = lwd)
panel.abline(v = 0, col = col.line, lty = lty, lwd = lwd)
if (!is.null(se)) {
se <- as.numeric(se[subscripts])
panel.segments(x - 1.96 * se, y, x + 1.96 * se, y,
col = "black")
}
panel.xyplot(x, y, pch = pch, ...)
}
f <- function(nx, ...) {
xt <- x[[nx]]
ss <- stack(xt)
mtit <- if (main)
nx
ss$ind <- factor(as.character(ss$ind), levels = colnames(xt))
ss$.nn <- rep.int(reorder(factor(rownames(xt)), xt[[1]],
FUN = mean, sort = sort), ncol(xt))
se <- NULL
if (!is.null(pv <- attr(xt, "postVar")))
se <- unlist(lapply(1:(dim(pv)[1]), function(i) sqrt(pv[i, i, ])))
#############################################################
# Next line is the inseerted line to deal with clmm objects
#############################################################
if (!is.null(cv <- attr(xt, "condVar"))) se <- as.vector(unlist(cv))
dotplot(.nn ~ values | ind, ss, se = se, prepanel = prepanel.ci,
panel = panel.ci, xlab = NULL, main = mtit, ...)
}
setNames(lapply(names(x), f, ...), names(x))
}
我开始尝试破解 lme4:::dotplot.ranef.mer
的内部结构,但事实证明使用 reshape2::melt
和 ggplot2
更容易做到这一点。抱歉,如果您非常喜欢 lattice
...
顺便请注意,从技术上讲,这些不是 "confidence intervals"(因为预测的条件模式在技术、常客意义上不是 "estimates")...
将条件模式的点估计和 SE 重新排列成有用的形状:
library(reshape2)
melt.ranef.clmm <- function(re,cv) {
reList <- lapply(re,
function(x) {
x$id <- reorder(factor(rownames(x)),x[,1])
return(melt(x,id.var="id"))
})
cvList <- lapply(cv,melt,id.var=NULL,value.name="se")
mm <- Map(cbind,reList,cvList)
return(mm)
}
将此应用于模型(m1
是拟合模型):
ss <- melt.ranef.clmm(ranef(m1),condVar(m1))
剧情:
library(ggplot2); theme_set(theme_bw())
ggplot(ss[[1]],aes(value,id))+
geom_errorbarh(aes(xmin=value-1.96*se,xmax=value+1.96*se),
height=0)+
ggtitle(names(ss)[1])+
geom_point(colour="blue")+
facet_wrap(~variable,scale="free_x")