Zeichnen des linearen R-Modells lm () mit Scatterplot3d über die Funktion $ plane3d
Stackoverflow-Community,
Ich möchte die Ergebnisse von Rs lm()als Ebene in einem 3D-Diagramm darstellen, das mit dem scatterplot3d()Befehl aus dem R-Paket Scatterplot3d erstellt wurde. Abhängig von meiner Methode, über die $plane3d()Funktion grafisch darzustellen, werden immer wieder mehrere Fehler angezeigt .
Zunächst einige reproduzierbare Daten - Schritt 1: Erstellen des Datenrahmens
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))
Schritt 2 - Anpassen des linearen Modells
lms <- lm(elem$co2 ~ elem$pH + elem$water_Loss + elem$elev + I(elem$pH * elem$water_Loss * elem$elev))
summary(lms)
Zu beachten: Es gibt keine lms$model$x und lms$model$y-Parameter zu den Ergebnissen dieses linearen Modells
Schritt 3 - Erstellen des 3D-Diagramms
library(scatterplot3d)
s3d <- scatterplot3d(elem[, -4], pch = 19, type = "p", grid = TRUE, box = FALSE, angle = 55)
Um das Streudiagramm + lm()Ergebnis grafisch darzustellen , s3d$plane3d()wird das direkt nach dem ersten Zeichnen des Diagramms ausgeführt.
So was:
s3d <- scatterplot3d(elem[, -4], pch = 19, type = "p", grid = TRUE, box = FALSE, angle = 55) s3d$plane3d()
In Zukunft werde ich jedoch nur den s3d$plane3d()Teil angeben .
Hier kommt das Problem ins Spiel. Ich werde drei verschiedene Möglichkeiten hervorheben, wie ich versucht habe, das lineare Modell in diesem Diagramm anzuzeigen
Versuch 1: Zeichnen Sie die Ergebnisse von lms direkt
s3d$plane3d(lms, draw_polygon = TRUE, draw_lines = TRUE)
Was den folgenden Fehler erzeugt:
Fehler in xy.coords (x, y, setLab = FALSE): Die Längen 'x' und 'y' unterscheiden sich
Um dies zu beheben, ging ich hierher: Die Längen 'x' und 'y' unterscheiden sich beim Plotten
Wie in dem Beitrag vorgeschlagen, habe ich das Flag verwendet, lm(x = TRUE, y = TRUE)aber ich hatte immer noch keine solchen Parameter in den lm()Ergebnissen, um das überprüfen zu können, length()und dies funktionierte nicht.
Versuch 2: Angabe der x-, y- und z-Koordinaten mit dem Achsenabschnitt im Streudiagramm
Ich folgte diesem Vorschlag, um dies zu tun: R - Erweitern des linearen Modells über Scatterplot3d hinaus
Für das Intercept-Flag habe ich den folgenden Code verwendet: lms$coefficientsund den Wert unter (Intercept) übernommen.
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 )
Was den folgenden Fehler erzeugt:
Fehler in x.coef * x.scal: nicht numerisches Argument für den Binäroperator
Versuch 3: Zeichnen einzelner Koeffizienten und Versuch, Polygone und Linien zu zeichnen
Ich habe es auf diese Weise versucht, nachdem ich die Dokumentation in R für den planes3d()Befehl von {rgl} gelesen hatte
Ermitteln der Koeffizienten:
coefs <- coef(lms) ; coefs
s3d$plane3d(a = -5.901006e-02 , b = -1.546285e+01, c = -2.946729e-04, Intercept = 3.010033e+00)
Was den folgenden Fehler erzeugt:
Fehler in x.coef * x.scal: nicht numerisches Argument für den Binäroperator
Ich habe auch versucht, die Flags draw_polygon = TRUE, draw_lines = TRUEzum obigen Befehl hinzuzufügen , was nur einen weiteren Fehler ergab - unter dem Strich - hat nicht funktioniert.
Zu diesem Zeitpunkt bin ich völlig ratlos (ich habe viele andere Methoden ausprobiert - die ich nicht alle veröffentlichen kann). Ich möchte um Hilfe bitten, um herauszufinden, was genau mir fehlt, um diese Ebene in diesem Diagramm darzustellen. Jede Hilfe wird sehr geschätzt.
Vielen Dank.
Antworten
scatterplot3d()Modelle mit größerer Dimensionalität (als 2 Eingabedimensionen und 1 Ausgabedimension) können nicht in 3D dargestellt werden. Tatsächlich wäre ein solches Diagramm nicht gültig, da die Werte in den zusätzlichen Dimensionen für die verschiedenen Beobachtungen vermutlich unterschiedlich sein werden. Sie würden daher beeinflussen, wie genau das Modell passt, und eine Darstellung, die diese vernachlässigt, wäre irreführend.
Das heißt, s3d$plane3dgeht nicht gut mit fehlerhaften Eingaben um. Wenn beispielsweise die Dimensionalität des Modells nicht den Erwartungen entspricht, werden verwirrende Fehlermeldungen zurückgegeben (wie Sie gesehen haben). Es gibt auch keine Hilfe für diese Funktion und tatsächlich ist die Funktion in einer anderen Funktion im Paket verschachtelt und hat keine Kommentare. Infolgedessen ist dies alles ziemlich schwer zu verstehen, aber wenn Sie tiefer gehen möchten, müssen Sie den Code des Pakets lesen, den Sie hier finden .
Sie können Ihr Diagramm absolut eine partielle Regressionsfläche anzeigen lassen, aber Sie müssen plot3d mitteilen, welche Dimensionen Sie möchten. Im Wesentlichen würden Sie eine Ebene im 3D-Raum zeichnen, wo Sie eine Hyperebene im höherdimensionalen Raum haben sollten.
Ihr Versuch 2 war auf dem richtigen Weg. Aber Sie geben nicht das richtige Argument ab. Die Funktion will x.coefund y.coefetc. aber nicht xyz.coordsund versucht daher anscheinend, die von Ihnen übergebenen Vektoren als Koeffizienten zu interpretieren und schlägt fehl. Sie könnten dies stattdessen tun:
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)))
Es ist jedoch unwahrscheinlich, dass Sie die Regressionsfläche in Ihrem Diagramm überhaupt sehen, da der Einfluss der Dimensionen, die Sie nicht zeichnen, sie aus dem sichtbaren Bereich Ihrer Figur verschiebt. Wenn Sie es mit Gewalt zurückziehen möchten, müssen Sie Ihren Abschnitt ändern:
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)))
Aber die Ebene, die Sie sehen, ist eigentlich nur ein 2D-Schnitt durch die 3D-Oberfläche, die Ihre Regression darstellt, und repräsentiert genau nur die Beobachtungen, die Sie zufällig haben ( elevin Ihrem Fall) genau den Durchschnittswert in dieser dritten Dimension .
Genau das würden Sie erhalten, wenn Sie die Regression ohne die zusätzlichen Dimensionen ausführen würden. Sie können das also genauso gut tun und planen.