Como plotar o modelo linear R lm () usando scatterplot3d via função $ plane3d

Nov 06 2020

Comunidade Stackoverflow,

Estou procurando plotar os resultados de R lm()como um plano em um gráfico 3D feito com o scatterplot3d()comando do pacote R scatterplot3d. Continuo recebendo vários erros, dependendo do meu método de tentar fazer o gráfico por meio da $plane3d()função.

Primeiro, alguns dados reproduzíveis - Etapa 1: fazer o quadro de dados

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

Etapa 2 - ajuste do modelo linear

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

Para observar: não há lms$model$x e lms$model$parâmetros y nos resultados deste modelo linear

Etapa 3 - fazer o gráfico 3D

library(scatterplot3d)

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

Para representar graficamente o gráfico de dispersão + lm()resultado, o s3d$plane3d()é executado diretamente após traçar o gráfico primeiro.

Como isso:

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

Porém, avançando, indicarei apenas a s3d$plane3d()parte.

É aqui que entra o problema. Vou destacar três maneiras diferentes que tentei fazer com que o modelo linear fosse exibido neste gráfico

Tentativa 1: traçando os resultados dos filmes diretamente

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

O que produz o seguinte erro:

Erro em xy.coords (x, y, setLab = FALSE): os comprimentos 'x' e 'y' diferem

Olhando para consertar isso, eu fui aqui: comprimentos de 'x' e 'y' diferem ERROR durante a plotagem

Como o post sugerido, usei o flag lm(x = TRUE, y = TRUE)mas ainda não tinha esses parâmetros nos lm()resultados para poder verificar o length()e isso não funcionou.

Tentativa 2: Especificando as coordenadas x, y, z com interceptação no gráfico de dispersão

Eu estava seguindo esta sugestão para fazer isso: R - Estendendo o modelo linear além do gráfico de dispersão3d

Para o sinalizador de interceptação, usei o seguinte código: lms$coefficientse peguei o valor em (Intercept).

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  )

O que produz o seguinte erro:

Erro em x.coef * x.scal: argumento não numérico para operador binário

Tentativa 3: traçar coeficientes individuais e tentar desenhar polígonos e linhas

Tentei desta forma depois de ler a documentação em R para o planes3d()comando de {rgl}

Obtendo os coeficientes:

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

O que produz o seguinte erro:

Erro em x.coef * x.scal: argumento não numérico para operador binário

Eu também tentei adicionar os sinalizadores draw_polygon = TRUE, draw_lines = TRUEao comando acima, o que só deu mais um erro - linha inferior - não funcionou.

Neste ponto, estou completamente perdido (tentei muitos outros métodos - que não consigo postar todos). Eu gostaria de pedir ajuda na tentativa de apontar exatamente o que estou perdendo para traçar este plano neste gráfico. Toda e qualquer ajuda será muito apreciada.

Obrigado.

Respostas

1 0range Nov 19 2020 at 00:15

scatterplot3d()não será capaz de plotar modelos com dimensionalidade maior (do que 2 dimensões de entrada e 1 dimensão de saída) em 3D. Na verdade, tal gráfico não seria válido, pois os valores nas dimensões adicionais serão presumivelmente diferentes para as diferentes observações. Eles influenciam, portanto, o quão próximo o modelo se ajusta e um gráfico que os negligencia seria enganoso.

Dito isso, s3d$plane3dnão lida muito bem com entrada malformada. Por exemplo, se a dimensionalidade do modelo não for a esperada, ele retornará mensagens de erro confusas (como você viu). Também não há ajuda para esta função e, de fato, a função está aninhada em outra função do pacote e não possui comentários. Como resultado, tudo isso será bastante difícil de entender, mas se você quiser se aprofundar, deverá ler o código do pacote, que pode ser encontrado aqui .

Você pode absolutamente ter seu gráfico mostrando uma superfície de regressão parcial, mas você tem que dizer ao plot3d, quais dimensões você deseja. Essencialmente, você traçaria um plano no espaço 3D onde deveria ter um hiperplano no espaço dimensional superior.

Sua tentativa 2 estava no caminho certo. Mas você não entrega o argumento certo. A função deseja x.coefe y.coefetc., mas não xyz.coordse, portanto, aparentemente tenta interpretar os vetores que você entrega como coeficiente e falha. Você poderia fazer isso em vez disso:

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

No entanto, é improvável, no entanto, que você mesmo veja a superfície de regressão em sua plotagem, porque a influência das dimensões que você não plota a desloca para fora da área visível de sua figura. Se você quiser puxá-lo de volta à força, você deve modificar sua interceptação:

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

Mas o plano que você vê é na verdade apenas uma fatia 2d através da superfície 3d que é a sua regressão e representa com precisão apenas as observações que você tem exatamente o valor médio nessa terceira dimensão ( elevno seu caso).

Na verdade, isso é exatamente o que você obteria se executasse a regressão sem as dimensões adicionais; então você também pode fazer e planejar isso.