$ plane3d 함수를 통해 scatterplot3d를 사용하여 R 선형 모델 lm ()을 그리는 방법

Nov 06 2020

Stackoverflow 커뮤니티,

R 패키지 scatterplot3d lm()의 scatterplot3d()명령으로 만든 3d 그래프의 평면 으로 R의 결과를 플롯하려고합니다 . $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)

참고 : 작품은 없습니다$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()부분 만 표시하겠습니다 .

여기에서 문제가 발생합니다.이 그래프에 선형 모델을 표시하기 위해 시도한 세 가지 방법을 강조하겠습니다.

시도 1 : 작품의 결과를 직접 플로팅

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

다음과 같은 오류가 발생합니다.

xy.coords (x, y, setLab = FALSE) 오류 : 'x'및 'y'길이가 다릅니다.

이 문제를 해결하기 위해 여기에 갔다 : 플로팅 할 때 'x'와 'y'길이가 다릅니다.

제안 된 게시물처럼 플래그를 사용 lm(x = TRUE, y = TRUE)했지만 lm()결과에 이러한 매개 변수가 없어서 확인할 수 length()없었고 작동하지 않았습니다.

시도 2 : 산점도에서 절편을 사용하여 x, y, z 좌표 지정

나는 그렇게하기 위해이 제안을 따르고 있었다. R-산점도 3d를 넘어 선형 모델 확장

인터셉트 플래그의 경우 다음 코드를 사용하고 lms$coefficients(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  )

다음과 같은 오류가 발생합니다.

x.coef * x.scal 오류 : 이항 연산자에 대한 숫자가 아닌 인수

시도 3 : 개별 계수 플로팅 및 다각형 및 선 그리기 시도

planes3d(){rgl} 의 명령에 대한 R의 문서를 읽은 후 이렇게 시도했습니다.

계수 얻기 :

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위의 명령에 플래그를 추가하려고 시도했지만 또 다른 오류-결론-작동하지 않았습니다.

이 시점에서 나는 완전한 손실에 처해 있습니다 (다른 많은 방법을 시도했지만 모두 게시 할 수는 없습니다). 이 그래프에이 평면을 그리기 위해 내가 놓치고있는 것을 정확히 찾아내는 데 도움을 요청하고 싶습니다. 모든 도움을 주시면 대단히 감사하겠습니다.

감사합니다.

답변

1 0range Nov 19 2020 at 00:15

scatterplot3d()3D에서 더 큰 차원 (입력 차원 2 개 및 출력 차원 1 개보다)을 가진 모델을 플롯 할 수 없습니다. 사실, 추가 차원의 값은 관측치마다 다를 수 있으므로 이러한 플롯은 유효하지 않습니다. 따라서 모델이 얼마나 가깝게 적합하는지에 영향을 미치며이를 무시하는 플롯은 오해의 소지가 있습니다.

즉, s3d$plane3d잘못된 입력을 잘 처리하지 못합니다. 예를 들어, 모델의 차원이 예상 한 것과 다르면 혼란스러운 오류 메시지를 반환합니다 (본 것처럼). 이 함수에 대한 도움말도 없으며 실제로 함수는 패키지의 다른 함수에 중첩되어 있으며 주석이 없습니다. 결과적으로 이것은 모두 이해하기 어렵지만 더 깊이 들어가고 싶다면 여기에서 찾을 수있는 패키지의 코드를 읽어야합니다 .

플롯에 부분 회귀 표면이 표시되도록 할 수 있지만 원하는 차원을 plot3d에 알려야합니다. 기본적으로 더 높은 차원의 공간에 하이퍼 플레인이 있어야하는 3D 공간에서 평면을 그릴 것입니다.

귀하의 시도 2는 올바른 방향으로 진행되었습니다. 그러나 당신은 올바른 주장을 넘겨주지 않습니다. 이 기능은 원 x.coef하고 y.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)))

그러나 당신이 보는 평면은 실제로 당신의 회귀 인 3 차원 표면을 통과하는 2 차원 슬라이스 일 뿐이며 정확히 그 3 차원 ( elev당신의 경우)에서 정확히 평균값을 가지는 관찰을 정확하게 나타냅니다 .

사실, 이것은 추가 차원없이 회귀를 실행하면 정확히 얻을 수있는 것입니다. 그래서 당신은 그것을 수행하고 플롯하는 것이 좋습니다.