如何生成 b 样条曲面,比方说:
x=attitude$rating
y=attitude$complaints
z=attitude$privileges
将是样条基础的 x 和 y。z 是控制点的集合。
require(rms) # Harrell's gift to the R world.
# Better to keep the original names and do so within a dataframe.
att <- attitude[c('rating','complaints','privileges')]
add <- datadist(att) # records ranges and descriptive info on data
options(datadist="add") # need these for the rms functions
# rms-`ols` function (ordinary least squares) is a version of `lm`
mdl <- ols( privileges ~ rcs(rating,4)*rcs(complaints,4) ,data=att)
# Predict is an rms function that works with rms's particular classes
pred <- Predict(mdl, 'rating','complaints')
# bplot calls lattice functions; levelplot by default; this gives a "3d" plot
bplot(pred, yhat~rating+complaints, lfun=wireframe)
这是一个交叉限制三次样条模型。如果您想使用最喜欢的样条函数,那么请务必尝试一下。我对rcs
- 功能很幸运。
这给出了一个具有更少计算点的更开放的网格:
pred <- Predict(mdl, 'rating','complaints', np=25)
bplot(pred, yhat~rating+complaints, lfun=wireframe)
png()
bplot(pred, yhat~rating+complaints, lfun=wireframe)
dev.off()
您可以使用 jhoward 说明的 rgl 方法。str(pred) 的顶部看起来像:
str(pred)
Classes ‘Predict’ and 'data.frame': 625 obs. of 5 variables:
$ rating : num 43 44.6 46.2 47.8 49.4 ...
$ complaints: num 45 45 45 45 45 ...
$ yhat : num 39.9 39.5 39.1 38.7 38.3 ...
$ lower : num 28 28.3 27.3 25 22 ...
$ upper : num 51.7 50.6 50.9 52.4 54.6 ...
snipped
library(rgl)
open3d()
with(pred, surface3d(unique(rating),unique(complaints),yhat,alpha=.2))
with(att, points3d(rating,complaints,privileges, col="red"))
title3d(xlab="rating",ylab="complaints",zlab="privileges")
axes3d()
aspect3d(x=1,z=.05)
一旦您意识到没有关于该模型的不适当外推极端情况的数据,就很好地说明了外推的危险。rms 包有一个perimeter
函数,绘图函数有一个perim
参数,周边对象传递给该参数。
如果我理解你,你有 x、y 和 z 数据,并且你想在 x 和 y 上使用二元样条插值,使用 z 作为控制点。您可以interp(...)
在akima
包中执行此操作。
library(akima)
spline <- interp(x,y,z,linear=FALSE)
# rotatable 3D plot of points and spline surface
library(rgl)
open3d(scale=c(1/diff(range(x)),1/diff(range(y)),1/diff(range(z))))
with(spline,surface3d(x,y,z,alpha=.2))
points3d(x,y,z)
title3d(xlab="rating",ylab="complaints",zlab="privileges")
axes3d()
由于 x、y 和 x 高度相关,因此该图本身对您的数据集相当无趣。
编辑对 OP 评论的回应。
如果您想要一个 b 样条曲面,请尝试mba.surf(...)
使用不幸命名的MBA
包。
library(MBA)
spline <- mba.surf(data.frame(x,y,z),100,100)
library(rgl)
open3d(scale=c(1/diff(range(x)),1/diff(range(y)),1/diff(range(z))))
with(spline$xyz,surface3d(x,y,z,alpha=.2))
points3d(x,y,z)
title3d(xlab="rating",ylab="complaints",zlab="privileges")
axes3d()