Cómo trazar el modelo lineal R lm () usando scatterplot3d a través de la función $ plane3d

Nov 06 2020

Comunidad de Stackoverflow,

Estoy buscando trazar los resultados de R lm()como un plano en un gráfico 3d realizado con el scatterplot3d()comando del paquete R scatterplot3d. Sigo recibiendo múltiples errores, dependiendo de mi método para intentar graficar a través de la $plane3d()función.

Primero, algunos datos reproducibles - Paso 1: hacer el marco de datos

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))

Paso 2: ajuste del modelo lineal

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

A tener en cuenta: no hay lms$model$x y lms$model$y parámetros sobre los resultados de este modelo lineal

Paso 3: hacer el gráfico 3d

library(scatterplot3d)

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

Para graficar el gráfico de diagrama de dispersión + lm()resultado, s3d$plane3d()se ejecuta directamente después de trazar el gráfico primero.

Me gusta esto:

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

Sin embargo, avanzando, solo indicaré la s3d$plane3d()porción.

Aquí es donde entra el problema. Destacaré 3 formas diferentes en las que he intentado que el modelo lineal se muestre en este gráfico.

Intento 1: graficar los resultados de lms directamente

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

Lo que produce el siguiente error:

Error en xy.coords (x, y, setLab = FALSE): las longitudes de 'x' e 'y' difieren

Buscando arreglar esto, fui aquí: las longitudes 'x' e 'y' difieren ERROR al trazar

Como sugirió la publicación, usé la bandera lm(x = TRUE, y = TRUE)pero todavía no tenía tales parámetros en los lm()resultados para poder verificar length()y esto no funcionó.

Intento 2: especificar las coordenadas x, y, z con intersección en el diagrama de dispersión

Estaba siguiendo esta sugerencia para hacerlo: R - Extender el modelo lineal más allá de scatterplot3d

Para la bandera de intercepción, utilicé el siguiente código: lms$coefficientsy tomé el valor debajo de (Intercepción).

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  )

Lo que produce el siguiente error:

Error en x.coef * x.scal: argumento no numérico para el operador binario

Intento 3: trazar coeficientes individuales e intentar dibujar polígonos y líneas

Lo intenté de esta manera después de leer la documentación en R para el planes3d()comando de {rgl}

Obteniendo los coeficientes:

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

Lo que produce el siguiente error:

Error en x.coef * x.scal: argumento no numérico para el operador binario

También intenté agregar las banderas draw_polygon = TRUE, draw_lines = TRUEal comando anterior, que solo dio otro error, la línea inferior, no funcionó.

En este punto, estoy completamente perdido (he probado muchos otros métodos, que no puedo publicar todos). Me gustaría pedir ayuda para tratar de precisar qué es exactamente lo que me falta para trazar este plano en este gráfico. Cualquier ayuda será muy apreciada.

Gracias.

Respuestas

1 0range Nov 19 2020 at 00:15

scatterplot3d()no podrá trazar modelos con una dimensionalidad mayor (que 2 dimensiones de entrada y 1 dimensión de salida) en 3D. De hecho, tal gráfico no sería válido ya que los valores en las dimensiones adicionales presumiblemente serán diferentes para las diferentes observaciones. Por lo tanto, influirían en qué tan cerca se ajusta el modelo y una trama que los ignore sería engañoso.

Dicho esto, s3d$plane3dno maneja muy bien la entrada con formato incorrecto. Por ejemplo, si la dimensionalidad del modelo no es la esperada, devolverá mensajes de error confusos (como ha visto). Tampoco hay ayuda para esta función y, de hecho, la función está anidada en otra función del paquete y no tiene comentarios. Como resultado, todo esto será bastante difícil de entender, pero si desea profundizar, debe leer el código del paquete, que puede encontrar aquí .

Puede hacer que su gráfico muestre una superficie de regresión parcial, pero tiene que decirle a plot3d qué dimensiones desea. Básicamente, estarías trazando un plano en el espacio 3D donde deberías tener un hiperplano en un espacio dimensional superior.

Tu intento 2 estaba en el camino correcto. Pero no entrega el argumento correcto. La función quiere x.coefy y.coefetc. pero no xyz.coordsy, por lo tanto, aparentemente intenta interpretar los vectores que le entregas como coeficientes y falla. En su lugar, podrías hacer esto:

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)))

Sin embargo, es poco probable que veas la superficie de regresión en tu gráfico, porque la influencia de las dimensiones que no trazas la desplazará fuera del área visible de tu figura. Si desea retirarlo por la fuerza, debe modificar su intercepción:

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)))

Pero el plano que ve es en realidad solo un corte en 2d a través de la superficie en 3D que es su regresión y solo representa con precisión las observaciones que tiene exactamente el valor promedio en esa tercera dimensión ( eleven su caso).

De hecho, esto es exactamente lo que obtendría si ejecutara la regresión sin las dimensiones adicionales; así que también podría hacerlo y trazarlo.