在R中对具有负值的3D loess平滑设置上限为0。

9
我有一个有点奇怪的问题,但希望有人能帮助我。我试图创建一个湖底表面图,然后添加一些显示水生植物频率的点,以便可视化湖泊中的水生植物分布情况。
目前,我正在使用R中的scatterplot3d和lattice包分别创建散点图3D和线框图来创建表面图。为了实现我感兴趣的绘图类型,我已将深度转换为负值(将湖面视为z轴上的0),然后通过纬度和经度坐标创建了一个深度的loess模型。然而,我遇到的一个问题是loess模型预测正深度(当然,在湖中是不可能的;只能从深度为0处进入水柱)。
示例
x <- seq(1,100,1)
y <- seq(1,100,1)
depth <- rbeta(100, 1, 50)*100
depth <- -depth

dep.lo <- loess(depth~x*y, degree=2, span=.25) # this shows a big warning, but it works
coord.fit <- expand.grid(x=x, y=y)
coord.fit$depth <- as.numeric(predict(dep.lo, newdata=coord.fit))
range(coord.fit$depth)
  # -14.041011   6.986745

从图中可以看出,我的深度从-14到接近7。是否有一种方法可以设置loess模型的上限,以便我的模型不会达到这些正值?

谢谢任何帮助,
保罗


5
请使用 mgcv 包,采用对数链接的 GAMM 拟合方法。 - Ben Bolker
1个回答

7

如果您想使用loess模型,可以使用转换方法确保变量保持为负数。您之前收到的警告是因为所有点都在一条直线上,因此稍微更改数据即可:

set.seed(123)
n = 100
x <- c(0, runif(n, min=1, max=100), 100)
y <- c(0, runif(n, min=1, max=100), 100)
depth <- rbeta(n+2, 1, 50)*100
depth <- -depth
range(depth)

[1] -13.27248715  -0.01520178

使用您提供的原始示例,您将获得以下结果:

dep.lo <- loess(depth~x*y, degree=2, span=.25) 
coord.fit <- expand.grid(x=seq(1,100,1), y=seq(1,100,1))
coord.fit$depth <- as.numeric(predict(dep.lo, newdata=coord.fit))
range(coord.fit$depth)

[1] -7.498542  2.397855

转换可以是log(-depth),例如:
tiny = 1e-3
nlogdepth = log(-depth + tiny) # adding 'tiny' to ensure depth is not 0
dep.lo <- loess(nlogdepth~x*y, degree=2, span=.25)
coord.fit <- expand.grid(x=x, y=y)
coord.fit$depth <- -exp(as.numeric(predict(dep.lo, newdata=coord.fit))) + tiny
range(coord.fit$depth)

[1] -16.9366043  -0.1091614

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接