提问人:Nate 提问时间:3/3/2023 更新时间:3/18/2023 访问量:226
更改 draw() plot 的正确 R 语法 - gratia package
Correct R syntax for changing draw() plot - gratia package
问:
我需要帮助翻译“对我的数据中空间变化的长期趋势进行建模”,并将下面的图更改为正确的 R 语法。
我希望在 x 轴上显示经度,在 y 轴上显示纬度,并在每个日历年(“CYR”)上显示一个面板。不过,在我的平滑函数中更改变量的顺序会给我这个错误:
...ti(Latitude, CYR, Longitude, d = c(2,1), bs = c('ds','tp'), k = c(25, 14)), ..
...ti(CYR, Latitude, Longitude, d = c(2,1), bs = c('ds','tp'), k = c(25, 14)), ..
Error in check.term(termi, rec) :
bam can not discretize with this nesting structure
它也以某种方式与我的其他协变量有关(删除它们可以阻止错误,但我无法正确“绘制”绘图)。
library(mgcv)
library(gratia)
m <- bam(occur ~ s(temp) +
sal +
s(DO) +
sed_depth +
water_depth +
s(fCYR, bs = "re") + # Long-term trend
# Spatial variation
s(Longitude, Latitude, k = 100, bs = 'tp') + # Try bs = tp (default)
s(fSite, bs = "re") + # Repeated measures design
# long-term trend varies spatially (code I need to change, I think)
ti(Latitude, CYR, Longitude, d = c(2,1), bs = c('ds','tp'), k = c(25, 14)),
data = toad,
method = 'fREML',
# knots = knots,
nthreads = 4,
discrete = TRUE,
family = binomial(link = "logit"),
# select = TRUE,
gamma = 1.5)
draw(m, select = 6)
答:
如果你知道一些ggplot,那么手动完成这个操作相对容易:
library("gratia")
library("mgcv")
library("ggplot2")
library("dplyr")
df <- data_sim("eg1", n = 1000, dist = "normal", scale = 2, seed = 1)
m <- gam(y ~ te(x2, x0, x1, k = c(5, 20), d = c(1,2), bs = c("ds", "cr")),
data = df, method = "REML")
sms <- smooth_estimates(m, n = 50, n_3d = 10)
est_lim <- c(-1, 1) * max(abs(sms[["est"]]), na.rm = TRUE)
sms |>
mutate(fx2 = factor(x2)) |>
ggplot(aes(x = x0, y = x1, fill = est, group = fx2)) +
geom_raster(aes(x = x0, y = x1, fill = est, group = fx2)) +
geom_contour(aes(z = est, group = fx2, fill = NULL), colour = "black") +
facet_wrap(~ fx2) +
scale_fill_distiller(palette = "RdBu", type = "div") +
expand_limits(fill = est_lim)
在这里,我手动识别示例中的第二个平滑是 2d 样条,因此我知道要在绘图的 x 轴和 y 轴上绘制和。x0
x1
该代码产生
在包代码中执行此操作比较棘手,因此它会自动发生,如果模型中没有提示(没有 2d 平滑),并且您希望能够指定绘制的内容,则编写一个接口更难。我想我很快就会在 {gratia} 中提供前者(识别 2d 平滑并将其绘制在 x 轴和 y 轴上,在其他变量上刻面),但更难的部分将需要更多的思考,并且可能无法直接从类似的命令中完成。draw(m)
为了实现完全控制(例如,为小平面指定特定的 [漂亮] 值),请在以下位置生成要评估平滑度的值的数据切片:x2
ds <- data_slice(m, x0 = evenly(x0, n = 50), x1 = evenly(x1, n = 50),
x2 = seq(0, 1, by = 0.25))
sms <- smooth_estimates(m, data = ds)
est_lim <- c(-1, 1) * max(abs(sms[["est"]]), na.rm = TRUE)
sms |>
ggplot(aes(x = x0, y = x1, fill = est, group = x2)) +
geom_raster(aes(x = x0, y = x1, fill = est, group = x2)) +
geom_contour(aes(z = est, group = x2, fill = NULL), colour = "black") +
facet_wrap(~ x2) +
scale_fill_distiller(palette = "RdBu", type = "div") +
expand_limits(fill = est_lim)
这会产生
从版本 0.8.1.25(撰写本文时软件包的开发版本)开始,{gratia} 现在应该能够自动处理此问题。
library("gratia")
library("mgcv")
library("ggplot2")
library("dplyr")
df <- data_sim("eg1", n = 1000, dist = "normal", scale = 2, seed = 1)
m <- gam(y ~ te(x0, x1, x2, k = c(25, 10), d = c(1,2), bs = c("cr", "ds")),
data = df, method = "REML")
draw(m, n = 25)
生产
可以看出,它已经在面板和小平面上绘制了 2D Duchon 样条,尽管在公式中定义项时项的排序方式不是这样。x0
te()
与我对 OP 问题的评论相反,这个(行为)仅在 0.8.1.25 中添加; .24 仅添加了对及其方法的支持。draw.gam()
smooth_estimates()
draw()
我将其作为单独的答案发布,因为这种新行为仅适用于 2D 边缘平滑;如果我们有 ,代码目前没有确定我们可以通过在面板的 x 和 y 轴上生成 和 的数据来做得更好,然后 facet by 和 。在这种情况下,您仍然需要我发布的原始答案中的想法来手动生成所需的输出。te(x0, x1, x2, x3, bs = c("cr", "ds"), d = c(1, 3))
x1
x2
x3
x1
评论
case_match
update.packages(ask = FALSE, checkBuilt = TRUE, Ncpus = X)
X
smooth_estimates()
draw()
smooth_estimates()
smooth_estimates()
year
评论
d
bs
ti(CYR, Latitude, Longitude, d = c(1,2), bs = c("tp", "ds"), ....)
bam()