Come tracciare il modello lineare R lm () usando scatterplot3d tramite la funzione $ plane3d

Nov 06 2020

Comunità Stackoverflow,

Sto cercando di tracciare i risultati di R lm()come un piano in un grafico 3D realizzato con il scatterplot3d()comando dal pacchetto R scatterplot3d. Continuo a ricevere più errori, a seconda del mio metodo di tentativo di rappresentare graficamente tramite la $plane3d()funzione.

Innanzitutto, alcuni dati riproducibili - Passaggio 1: creazione del data-frame

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

Passaggio 2: adattamento del modello lineare

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

Da notare: non ci sono lms$model$x e lms$model$y parametri sui risultati di questo modello lineare

Passaggio 3: creazione del grafico 3D

library(scatterplot3d)

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

Per rappresentare graficamente il grafico a dispersione + il lm()risultato, s3d$plane3d()viene eseguito direttamente dopo aver tracciato prima il grafico.

Come questo:

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

Tuttavia, andando avanti, indicherò solo la s3d$plane3d()parte.

È qui che entra in gioco il problema. Evidenzierò 3 diversi modi in cui ho provato a visualizzare il modello lineare su questo grafico

Tentativo 1: tracciare direttamente i risultati di lms

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

Che produce il seguente errore:

Errore in xy.coords (x, y, setLab = FALSE): le lunghezze 'x' e 'y' differiscono

Cercando di risolvere questo problema, sono andato qui: le lunghezze 'x' e 'y' differiscono ERRORE durante la stampa

Come suggerito dal post, ho usato il flag lm(x = TRUE, y = TRUE)ma non avevo ancora tali parametri nei lm()risultati per poterlo controllare length()e questo non ha funzionato.

Tentativo 2: specificare le coordinate x, y, z con l'intercetta nel grafico a dispersione

Stavo seguendo questo suggerimento per farlo: R - Extending Linear Model oltre scatterplot3d

Per il flag di intercettazione, ho usato il seguente codice: lms$coefficientse ho preso il valore sotto (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  )

Che produce il seguente errore:

Errore in x.coef * x.scal: argomento non numerico per l'operatore binario

Tentativo 3: tracciare i coefficienti individuali e tentare di disegnare poligoni e linee

Ho provato in questo modo dopo aver letto la documentazione in R per il planes3d()comando da {rgl}

Ottenere i coefficienti:

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

Che produce il seguente errore:

Errore in x.coef * x.scal: argomento non numerico per l'operatore binario

Ho anche provato ad aggiungere i flag draw_polygon = TRUE, draw_lines = TRUEal comando precedente, che ha dato solo un altro errore - in fondo - non ha funzionato.

A questo punto, sono completamente perso (ho provato molti altri metodi, che non posso pubblicare tutti). Vorrei chiedere aiuto per cercare di individuare esattamente cosa mi manca per tracciare questo piano su questo grafico. Qualsiasi aiuto sarà molto apprezzato.

Grazie.

Risposte

1 0range Nov 19 2020 at 00:15

scatterplot3d()non sarà in grado di tracciare modelli con dimensionalità maggiore (di 2 dimensioni di input e 1 dimensione di output) in 3D. In effetti, un tale grafico non sarebbe valido poiché i valori nelle dimensioni aggiuntive saranno presumibilmente diversi per le diverse osservazioni. Influirebbero quindi sulla misura in cui il modello si adatta e una trama che li trascuri sarebbe fuorviante.

Detto questo, s3d$plane3dnon gestisce molto bene input non validi. Ad esempio, se la dimensionalità del modello non è quella prevista, restituirà messaggi di errore confusi (come hai visto). Inoltre non è disponibile alcuna guida per questa funzione e infatti la funzione è annidata in un'altra funzione nel pacchetto e non ha commenti. Di conseguenza sarà tutto abbastanza difficile da capire, ma se vuoi andare più a fondo devi leggere il codice del pacchetto, che puoi trovare qui .

Puoi assolutamente fare in modo che il tuo grafico mostri una superficie di regressione parziale, ma devi dire a plot3d quali dimensioni desideri. Essenzialmente dovreste tracciare un piano nello spazio 3D dove dovreste avere un iperpiano nello spazio dimensionale superiore.

Il tuo tentativo 2 era sulla strada giusta. Ma non consegni l'argomento giusto. La funzione vuole x.coefe così y.coefvia, ma non xyz.coordse quindi apparentemente cerca di interpretare i vettori che consegni come coefficiente e fallisce. Potresti farlo invece:

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

Tuttavia, è improbabile, tuttavia, che tu possa persino vedere la superficie di regressione nel tuo grafico, perché l'influenza delle dimensioni che non grafici la sposterà dall'area visibile della tua figura. Se vuoi ritirarlo con la forza, devi modificare la tua intercettazione:

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

Ma il piano che vedi è in realtà solo una sezione 2d attraverso la superficie 3D che è la tua regressione e rappresenta accuratamente solo le osservazioni che ti capita di avere esattamente il valore medio in quella terza dimensione ( elevnel tuo caso).

In effetti, questo è esattamente ciò che otterresti se eseguissi la regressione senza le dimensioni aggiuntive; quindi potresti anche farlo e tracciarlo.