1

Stackoverflow 社区,

我希望将 R 的结果绘制为使用R 包 scatterplot3d 中lm()的命令制作的 3d 图中的平面。scatterplot3d()我不断收到多个错误,具体取决于我尝试通过该$plane3d()函数绘制图表的方法。

首先,一些可重现的数据 - 第 1 步:制作数据框

elem <- data.frame(pH = c(8.12, 8.19, 6.09, 5.99, 5.18, 6.09, 5.40, 5.50, 4.93, 5.16, 7.57, 7.21, 5.13, 6.23, 5.72), 
              water_Loss = c(0.010, 0.005, 0.065, 0.120, 0.250, 0.305, 0.100, 0.020, 0.430, 0.060, 0.065, 0.050, 0.025, 0.050, 0.020), 
              elev = c(2397, 2393, 2593, 2599, 2741, 2774, 2979, 2787, 3173, 3370, 2147, 2130, 2374, 2359, 2643), 
              co2 = c(1.8410, 1.9810, 2.0110, 1.8960, 1.3060, 2.0160, 1.7360, 1.5860, 1.6360, 1.9665, 1.6360, 1.7660, 1.9760, 2.7510, 1.3310))

第 2 步 - 拟合线性模型

lms <- lm(elem$co2 ~ elem$pH + elem$water_Loss + elem$elev + I(elem$pH * elem$water_Loss * elem$elev))
summary(lms)

注意:这个线性模型的结果没有 lms$model$x 和 lms$model$y 参数

第 3 步 - 制作 3d 图

library(scatterplot3d)

s3d <- scatterplot3d(elem[, -4], pch = 19, type = "p", grid = TRUE, box = FALSE, angle = 55)

要绘制散点图 +lm()结果,s3d$plane3d()首先绘制图形后直接运行。

像这样:

s3d <- scatterplot3d(elem[, -4], pch = 19, type = "p", grid = TRUE, box = FALSE, angle = 55) s3d$plane3d()

但是,继续前进,我只会指出s3d$plane3d()部分。

这就是问题所在。我将重点介绍我尝试将线性模型显示在此图上的 3 种不同方法

尝试1:直接绘制lms的结果

s3d$plane3d(lms, draw_polygon = TRUE, draw_lines = TRUE)

这会产生以下错误:

xy.coords(x, y, setLab = FALSE) 中的错误:“x”和“y”长度不同

为了解决这个问题,我去了这里:'x' and 'y' lengths different ERROR when plotting

就像帖子建议的那样,我使用了标志lm(x = TRUE, y = TRUE),但结果中仍然没有这样的参数lm()可以检查length(),这不起作用。

尝试 2:在散点图中用截距指定 x、y、z 坐标

我按照这个建议这样做:R - Extending Linear Model beyond scatterplot3d

对于拦截标志,我使用了以下代码:lms$coefficients并取了(拦截)下的值。

s3d$plane3d(xyz.coords(x = as.numeric(lms$model$`elem$pH`), y = as.numeric(lms$model$`elem$water_Loss`), z = as.numeric(lms$model$`elem$elev`)), Intercept = 3.010033e+00  )

这会产生以下错误:

x.coef * x.scal 中的错误:二进制运算符的非数字参数

尝试 3:绘制单个系数并尝试绘制多边形和线条

planes3d()在阅读了 R 中来自 {rgl}的命令的文档后,我尝试了这种方式

获取系数:

coefs <- coef(lms) ; coefs
s3d$plane3d(a = -5.901006e-02 , b = -1.546285e+01, c = -2.946729e-04, Intercept = 3.010033e+00)

这会产生以下错误:

x.coef * x.scal 中的错误:二进制运算符的非数字参数

我还尝试将标志添加draw_polygon = TRUE, draw_lines = TRUE到上述命令中,这只会给出另一个错误 - 底线 - 不起作用。

在这一点上,我完全不知所措(我尝试了许多其他方法 - 我无法将它们全部发布)。我想寻求帮助,以试图找出我在此图上绘制该平面所缺少的确切内容。任何和所有的帮助将不胜感激。

谢谢你。

4

1 回答 1

1

scatterplot3d()将无法在 3D 中绘制具有更大维度(超过 2 个输入维度和 1 个输出维度)的模型。事实上,这样的图是无效的,因为对于不同的观察,附加维度中的值可能会有所不同。因此,它们会影响模型的拟合程度,而忽略这些的情节会产生误导。

也就是说,s3d$plane3d不能很好地处理格式错误的输入。例如,如果模型的维度不符合预期,它将返回令人困惑的错误消息(如您​​所见)。该函数也没有任何帮助,实际上该函数嵌套在包中的另一个函数中并且没有注释。因此,这一切都很难理解,但如果你想深入了解,你必须阅读包的代码,你可以在这里找到。

您绝对可以让您的绘图显示部分回归曲面,但您必须告诉 plot3d,您想要哪些尺寸。本质上,您将在 3d 空间中绘制一个平面,您应该在高维空间中拥有一个超平面。

您的尝试 2 是在正确的轨道上。但是你没有交出正确的论据。该函数想要x.coefy.coef但不是xyz.coords,因此它显然试图将您移交的向量解释为系数并失败。你可以这样做:

s3d$plane3d(Intercept=lms$coefficients["(Intercept)"][[1]],
            x.coef=lms$coefficients["elem$pH"][[1]],
            y.coef=lms$coefficients["elem$water_Loss"][[1]],
            draw_polygon = TRUE, 
            draw_lines = TRUE, 
            polygon_args = list(col = rgb(0.8, 0.8, 0.8, 0.8)))

但是,您甚至不太可能在绘图中看到回归曲面,因为您未绘制的维度的影响会将其移出图形的可见区域。如果你想强行拉回来,你必须修改你的拦截:

average_intercept <- lms$coefficients["(Intercept)"][[1]] + lms$coefficients["elem$elev"][[1]] * mean(elem$elev)
s3d$plane3d(Intercept=average_intercept,
            x.coef=lms$coefficients["elem$pH"][[1]],
            y.coef=lms$coefficients["elem$water_Loss"][[1]],
            draw_polygon = TRUE, 
            draw_lines = TRUE, 
            polygon_args = list(col = rgb(0.8, 0.8, 0.8, 0.8)))

但是您看到的平面实际上只是通过 3d 表面的 2d 切片,这是您的回归,并且准确地仅代表您恰好具有该第三维(elev在您的情况下)中的平均值的观察结果。

事实上,如果你在没有额外维度的情况下运行回归,这正是你会得到的;所以你不妨这样做并绘制它。

于 2020-11-18T17:15:45.763 回答