Установка верхней границы 0 для трехмерного сглаживания лёсса с отрицательными значениями R

У меня немного странный вопрос, но надеюсь, что кто-то может мне помочь. Я пытаюсь создать график поверхности дна озера, а затем добавить несколько точек, показывающих частоту растений, чтобы визуально увидеть, где водные растения встречаются по всему озеру.

Прямо сейчас я работаю над созданием поверхностного графика как в scatterplot3d, так и в wireframe, используя пакеты scatterplot3d и grid, соответственно, в R. Чтобы получить интересующий меня тип графика, я преобразовал глубины в отрицательные значения (представьте себе поверхность воды озера как 0 по оси z), затем создал лёссовую модель глубины по координатам широты и долготы. Однако у меня возникла одна проблема: лёссовая модель предсказывает положительные глубины (что, конечно, невозможно в озере, спуститься в толщу воды можно только с глубины 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. Есть ли способ установить верхнюю границу для модели лёсса, чтобы моя модель не достигала таких положительных значений?

Спасибо за любую помощь,
Пол


person logicForPresident    schedule 16.01.2014    source источник
comment
попробуйте подобрать GAMM со ссылкой на журнал, используя пакет mgcv.   -  person Ben Bolker    schedule 20.01.2014


Ответы (1)


Если вы хотите использовать лёссовую модель, вы можете использовать преобразование, чтобы ваша переменная оставалась отрицательной. Вы получали предупреждения, потому что все ваши точки находились над линией, поэтому немного изменили данные:

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
person Ricardo Oliveros-Ramos    schedule 25.01.2014