Como plotar o modelo linear R lm () usando scatterplot3d via função $ plane3d
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
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.