drc :: 使用 ggplot2 绘制 drc 图
drc:: drc plot with ggplot2
我正在尝试用 ggplot2
重现 drc
情节。这是我的第一次尝试(下面给出了 MWE)。但是,我的 ggplot2 与基本 R 图略有不同。我想知道我是否遗漏了什么?
library(drc)
chickweed.m1 <- drm(count~start+end, data = chickweed, fct = LL.3(), type = "event")
plot(chickweed.m1, xlab = "Time (hours)", ylab = "Proportion germinated",
xlim=c(0, 340), ylim=c(0, 0.25), log="", lwd=2, cex=1.2)
library(data.table)
dt1 <- data.table(chickweed)
dt1Means1 <- dt1[, .(Germinated=mean(count)/200), by=.(start)]
dt1Means2 <- dt1Means1[, .(start=start, Germinated=cumsum(Germinated))]
dt1Means <- data.table(dt1Means2[start!=0], Pred=predict(object=chickweed.m1))
library(ggplot2)
ggplot(data= dt1Means, mapping=aes(x=start, y=Germinated)) +
geom_point() +
geom_line(aes(y = Pred)) +
lims(y=c(0, 0.25)) +
theme_bw()
已编辑
我遵循了here给出的方法(有一些变化)。
注意,您可以跳到最后一段以获得简单的答案。这个答案的其余部分记录了我是如何得出这个解决方案的
查看drc:::plot.drc的代码,我们可以看到最后一行看不见returns a data.frame retData
function (x, ..., add = FALSE, level = NULL, type = c("average",
"all", "bars", "none", "obs", "confidence"), broken = FALSE,
bp, bcontrol = NULL, conName = NULL, axes = TRUE, gridsize = 100,
log = "x", xtsty, xttrim = TRUE, xt = NULL, xtlab = NULL,
xlab, xlim, yt = NULL, ytlab = NULL, ylab, ylim, cex, cex.axis = 1,
col = FALSE, lty, pch, legend, legendText, legendPos, cex.legend = 1,
normal = FALSE, normRef = 1, confidence.level = 0.95)
{
# ...lot of lines omitted...
invisible(retData)
}
retData 包含拟合模型线的坐标,因此我们可以使用它来绘制 plot.drc 使用的相同模型
pl <- plot(chickweed.m1, xlab = "Time (hours)", ylab = "Proportion germinated",
xlim=c(0, 340), ylim=c(0, 0.25), log="", lwd=2, cex=1.2)
names(pl) <- c("x", "y")
ggplot(data= dt1Means, mapping=aes(x=start, y=Germinated)) +
geom_point() +
geom_line(data=pl, aes(x=x, y = y)) +
lims(y=c(0, 0.25)) +
theme_bw()
这与您使用 predict(object=chickweed.m1) 在 ggplot 中创建的版本相同。因此,区别不在于模型线,而在于绘制数据点的位置。我们可以通过将函数的最后一行从 invisible(retData)
更改为 list(retData, plotPoints)
来从 drc:::plot.drc 导出数据点。为了方便,我把drc:::plot.drc的全部代码复制到一个新的函数中。请注意,如果您希望复制此步骤,drcplot 调用的一些函数未在 drc 命名空间中导出,因此 drc:::
需要添加到对函数 parFct
的所有调用之前,addAxes
、brokenAxis
和 makeLegend
。
drcplot <- function (x, ..., add = FALSE, level = NULL, type = c("average",
"all", "bars", "none", "obs", "confidence"), broken = FALSE,
bp, bcontrol = NULL, conName = NULL, axes = TRUE, gridsize = 100,
log = "x", xtsty, xttrim = TRUE, xt = NULL, xtlab = NULL,
xlab, xlim, yt = NULL, ytlab = NULL, ylab, ylim, cex, cex.axis = 1,
col = FALSE, lty, pch, legend, legendText, legendPos, cex.legend = 1,
normal = FALSE, normRef = 1, confidence.level = 0.95)
{
# ...lot of lines omitted...
list(retData, plotPoints)
}
和运行这与您的数据
pl <- drcplot(chickweed.m1, xlab = "Time (hours)", ylab = "Proportion germinated",
xlim=c(0, 340), ylim=c(0, 0.25), log="", lwd=2, cex=1.2)
germ.points <- as.data.frame(pl[[2]])
drc.fit <- as.data.frame(pl[[1]])
names(germ.points) <- c("x", "y")
names(drc.fit) <- c("x", "y")
现在,用 ggplot2 绘制这些图就可以得到你想要的东西
ggplot(data= dt1Means, mapping=aes(x=start, y=Germinated)) +
geom_point(data=germ.points, aes(x=x, y = y)) +
geom_line(data=drc.fit, aes(x=x, y = y)) +
lims(y=c(0, 0.25)) +
theme_bw()
最后,将此图 (germ.points
) 的数据点值与原始 ggplot (dt1Means
) 中的数据点值进行比较,显示差异的原因。 dt1Means
中的计算点相对于 plot.drc 中的点提前了一个时间段。换句话说,plot.drc 将事件分配给它们发生的时间段的结束时间,而您将发芽事件分配给它们发生的时间间隔的开始。您可以简单地调整它,例如,使用
dt1 <- data.table(chickweed)
dt1[, Germinated := mean(count)/200, by=start]
dt1[, cum_Germinated := cumsum(Germinated)]
dt1[, Pred := c(predict(object=chickweed.m1), NA)] # Note that the final time period which ends at `Inf` can not be predicted by the model, therefore added `NA` in the final row
ggplot(data= dt1, mapping=aes(x=end, y=cum_Germinated)) +
geom_point() +
geom_line(aes(y = Pred)) +
lims(y=c(0, 0.25)) +
theme_bw()
从@dww 的回答中获得直觉,我不得不对我的原始代码进行两处小改动。只需在
中将 start!=0
替换为 end!=Inf
dt1Means1 <- dt1[, .(Germinated=mean(count)/200), by=.(start, end)]
dt1Means <- data.table(dt1Means2[start!=0], Pred=predict(object=chickweed.m1))
给出了正确的图表。
我非常喜欢 dww 提供的解决方案。我可以建议对此解决方案进行概括。通过将下面的行添加到 drc:::plotdrc()
的自写版本中,您可以概括解决方案。该函数采用 drc:::plotdrc()
函数的输入,但输出一个 ggplot-object,其规格与原始函数的默认底图输出相同。
只需将 invisible(retData, plotPoints)
替换为
result <- list(retData, plotPoints)
points <- as.data.frame(result[[2]])
drc.fit <- as.data.frame(result[[1]])
names(points) <- c("x", "y")
names(drc.fit) <- c("x", "y")`
gg_plot <- ggplot2::ggplot(data=points, aes(x = x, y = y)) +
geom_point() +
geom_line(data=drc.fit, aes(x = x, y = y)) +
scale_x_continuous(trans='log10', limits = xlim) +
ylab(ylab) +
xlab(xlab) +
lims(y = ylim) +
theme_bw()
return(gg_plot)`
我正在尝试用 ggplot2
重现 drc
情节。这是我的第一次尝试(下面给出了 MWE)。但是,我的 ggplot2 与基本 R 图略有不同。我想知道我是否遗漏了什么?
library(drc)
chickweed.m1 <- drm(count~start+end, data = chickweed, fct = LL.3(), type = "event")
plot(chickweed.m1, xlab = "Time (hours)", ylab = "Proportion germinated",
xlim=c(0, 340), ylim=c(0, 0.25), log="", lwd=2, cex=1.2)
library(data.table)
dt1 <- data.table(chickweed)
dt1Means1 <- dt1[, .(Germinated=mean(count)/200), by=.(start)]
dt1Means2 <- dt1Means1[, .(start=start, Germinated=cumsum(Germinated))]
dt1Means <- data.table(dt1Means2[start!=0], Pred=predict(object=chickweed.m1))
library(ggplot2)
ggplot(data= dt1Means, mapping=aes(x=start, y=Germinated)) +
geom_point() +
geom_line(aes(y = Pred)) +
lims(y=c(0, 0.25)) +
theme_bw()
已编辑
我遵循了here给出的方法(有一些变化)。
注意,您可以跳到最后一段以获得简单的答案。这个答案的其余部分记录了我是如何得出这个解决方案的
查看drc:::plot.drc的代码,我们可以看到最后一行看不见returns a data.frame retData
function (x, ..., add = FALSE, level = NULL, type = c("average",
"all", "bars", "none", "obs", "confidence"), broken = FALSE,
bp, bcontrol = NULL, conName = NULL, axes = TRUE, gridsize = 100,
log = "x", xtsty, xttrim = TRUE, xt = NULL, xtlab = NULL,
xlab, xlim, yt = NULL, ytlab = NULL, ylab, ylim, cex, cex.axis = 1,
col = FALSE, lty, pch, legend, legendText, legendPos, cex.legend = 1,
normal = FALSE, normRef = 1, confidence.level = 0.95)
{
# ...lot of lines omitted...
invisible(retData)
}
retData 包含拟合模型线的坐标,因此我们可以使用它来绘制 plot.drc 使用的相同模型
pl <- plot(chickweed.m1, xlab = "Time (hours)", ylab = "Proportion germinated",
xlim=c(0, 340), ylim=c(0, 0.25), log="", lwd=2, cex=1.2)
names(pl) <- c("x", "y")
ggplot(data= dt1Means, mapping=aes(x=start, y=Germinated)) +
geom_point() +
geom_line(data=pl, aes(x=x, y = y)) +
lims(y=c(0, 0.25)) +
theme_bw()
这与您使用 predict(object=chickweed.m1) 在 ggplot 中创建的版本相同。因此,区别不在于模型线,而在于绘制数据点的位置。我们可以通过将函数的最后一行从 invisible(retData)
更改为 list(retData, plotPoints)
来从 drc:::plot.drc 导出数据点。为了方便,我把drc:::plot.drc的全部代码复制到一个新的函数中。请注意,如果您希望复制此步骤,drcplot 调用的一些函数未在 drc 命名空间中导出,因此 drc:::
需要添加到对函数 parFct
的所有调用之前,addAxes
、brokenAxis
和 makeLegend
。
drcplot <- function (x, ..., add = FALSE, level = NULL, type = c("average",
"all", "bars", "none", "obs", "confidence"), broken = FALSE,
bp, bcontrol = NULL, conName = NULL, axes = TRUE, gridsize = 100,
log = "x", xtsty, xttrim = TRUE, xt = NULL, xtlab = NULL,
xlab, xlim, yt = NULL, ytlab = NULL, ylab, ylim, cex, cex.axis = 1,
col = FALSE, lty, pch, legend, legendText, legendPos, cex.legend = 1,
normal = FALSE, normRef = 1, confidence.level = 0.95)
{
# ...lot of lines omitted...
list(retData, plotPoints)
}
和运行这与您的数据
pl <- drcplot(chickweed.m1, xlab = "Time (hours)", ylab = "Proportion germinated",
xlim=c(0, 340), ylim=c(0, 0.25), log="", lwd=2, cex=1.2)
germ.points <- as.data.frame(pl[[2]])
drc.fit <- as.data.frame(pl[[1]])
names(germ.points) <- c("x", "y")
names(drc.fit) <- c("x", "y")
现在,用 ggplot2 绘制这些图就可以得到你想要的东西
ggplot(data= dt1Means, mapping=aes(x=start, y=Germinated)) +
geom_point(data=germ.points, aes(x=x, y = y)) +
geom_line(data=drc.fit, aes(x=x, y = y)) +
lims(y=c(0, 0.25)) +
theme_bw()
最后,将此图 (germ.points
) 的数据点值与原始 ggplot (dt1Means
) 中的数据点值进行比较,显示差异的原因。 dt1Means
中的计算点相对于 plot.drc 中的点提前了一个时间段。换句话说,plot.drc 将事件分配给它们发生的时间段的结束时间,而您将发芽事件分配给它们发生的时间间隔的开始。您可以简单地调整它,例如,使用
dt1 <- data.table(chickweed)
dt1[, Germinated := mean(count)/200, by=start]
dt1[, cum_Germinated := cumsum(Germinated)]
dt1[, Pred := c(predict(object=chickweed.m1), NA)] # Note that the final time period which ends at `Inf` can not be predicted by the model, therefore added `NA` in the final row
ggplot(data= dt1, mapping=aes(x=end, y=cum_Germinated)) +
geom_point() +
geom_line(aes(y = Pred)) +
lims(y=c(0, 0.25)) +
theme_bw()
从@dww 的回答中获得直觉,我不得不对我的原始代码进行两处小改动。只需在
中将start!=0
替换为 end!=Inf
dt1Means1 <- dt1[, .(Germinated=mean(count)/200), by=.(start, end)]
dt1Means <- data.table(dt1Means2[start!=0], Pred=predict(object=chickweed.m1))
给出了正确的图表。
我非常喜欢 dww 提供的解决方案。我可以建议对此解决方案进行概括。通过将下面的行添加到 drc:::plotdrc()
的自写版本中,您可以概括解决方案。该函数采用 drc:::plotdrc()
函数的输入,但输出一个 ggplot-object,其规格与原始函数的默认底图输出相同。
只需将 invisible(retData, plotPoints)
替换为
result <- list(retData, plotPoints)
points <- as.data.frame(result[[2]])
drc.fit <- as.data.frame(result[[1]])
names(points) <- c("x", "y")
names(drc.fit) <- c("x", "y")`
gg_plot <- ggplot2::ggplot(data=points, aes(x = x, y = y)) +
geom_point() +
geom_line(data=drc.fit, aes(x = x, y = y)) +
scale_x_continuous(trans='log10', limits = xlim) +
ylab(ylab) +
xlab(xlab) +
lims(y = ylim) +
theme_bw()
return(gg_plot)`