Visualizzazione post con etichetta statistica. Mostra tutti i post
Visualizzazione post con etichetta statistica. Mostra tutti i post

mercoledì 25 dicembre 2024

Analisi delle distribuzioni dei dati nei gruppi/cluster

Se trovate utile l'impiego delle tecniche di clustering (o analisi dei gruppi) [1] come metodo per l'analisi esplorativa dei dati – ma anche se le affrontate per la prima volta – potrebbe interessarvi questo esempio.

Copiate lo script, incollatelo nella Console di R e premete ↵ Invio:

# ANALIZZARE LE DISTRIBUZIONI DEI DATI NEI CLUSTER con ggpairs  
#  
library(cluster) # carica il pacchetto per il clustering
library(factoextra) # carica un pacchetto addizionale per il clustering
library(GGally) # carica il pacchetto che estende le funzioni di ggplot2
#
# preparazione dei dati
#
mydata <- read.table("c:/Rdati/ema.csv", header=TRUE, sep=";", dec=".") # importa i dati dei 643 casi
newdata <- subset(mydata, select=c("gr", "hb", "mcv", "hb_a2", "ferro")) # seleziona le variabili per il clustering
#
# clustering non gerarchico con il metodo di Rousseew (k-medoids)
#
myclust <- pam(newdata, 3, metric=c("euclidean"), stand=TRUE) # genera un oggetto 'pam' che contiene i risultati del clustering
fviz_cluster(myclust, myclust$cluster, labelsize=7, main = "Grafico dei cluster - metodo di Rousseew (k-medoids)") # grafico dei cluster per le prime due componenti principali
#

Vediamo di cosa si tratta. Abbiamo nel file ema.csv una raccolta di 643 casi dei quali abbiamo raccolto i risultati di tre analisi del sangue richieste a scopo diagnostico:
→ esame emocromocitometrico – del quale ci interessano in particolare i valori di: (i) gr la concentrazione degli eritrociti nel sangue (globuli rossi) espressa in migliaia di miliardi per litro di sangue 10¹²/L o in milioni per microlitro di sangue 10⁶/µL (le due espressioni sono numericamente equivalenti); (ii) hb la concentrazione dell'emoglobina espressa in grammi per decilitro di sangue g/dL; (iii) mcv il volume medio dei globuli rossi espresso in milionesimi di miliardesimo di litro (10-¹⁵) o femtolitri (fL);
→ emoglobina A2 – hb_A2 la variante fisiologica dell'emoglobina presente nell'adulto espressa come percentuale dell'emoglobina totale;
→ ferro – ferro la concentrazione del ferro espressa in microgrammi per decilitro di siero µg/dL. 

Sappiamo che i 643 casi comprendono:
→ soggetti sani, impiegati come controlli, con i risultati delle tre analisi all'interno dei valori fisiologici (valori "normali");
→ soggetti con alterazioni dell'esame emocromocitometrico e con carenza di ferro (confermata dalla diminuita concentrazione del ferro nel siero);
→  soggetti con alterazioni dell'esame emocromocitometrico e portatori del gene della beta-talassemia (confermato dall'aumento della percentuale di emoglobina A2);
→  soggetti con alterazioni dell'esame emocromocitometrico ma non classificabili ulteriormente con i dati disponibili.

Siamo interessati a una analisi esplorativa dei dati e, seguendo lo script, procediamo come segue.

1) Preparazione dei dati
Installiamo i tre pacchetti che ci servono, cluster, factoextra e GGally, quindi ci procuriamo i dati impiegati nell'esempio (per il file di dati trovate link e istruzioni alla pagina di Download):
→ effettuando il download del file di dati ema.csv
→ salvando il file nella cartella C:\Rdati\

Con la funzione read.table() importiamo i dati nell'oggetto mydata. Quindi con la funzione subset() riportiamo nell'oggetto newdata le sole variabili che ci interessano, cioè i risultati delle analisi indicate sopra (643 record), in cinque colonne:

> newdata
      gr   hb  mcv hb_a2 ferro
1   4.90 13.3 82.8   1.8   106
2   4.66 10.8 73.6   2.6   148
3   5.43 11.5 66.5   4.8   104
4   5.41 10.8 73.4   2.5    74
..........
642 5.28 11.0 65.4   1.9    11
643 4.03  7.2 55.0   1.9    21

2) Clustering non gerarchico (analisi dei gruppi)
A questo punto eseguiamo il clustering non gerarchico, lo facciamo impiegando il metodo di Rousseew. La prima funzione utilizzata è pam() che deriva il suo nome da "Partitioning Around Medoids", impiega l'algoritmo di clustering dei dati  k-medoids (un versione robusta dell'algoritmo k-means) e prevede come argomenti:
→ i dati newdata da impiegare;
→ il numero di cluster, in questo caso 3, in cui classificare i dati;
→ la metrica da impiegare che è "euclidean" (in alternativa può essere "manhattan");
→ stand=TRUE che impone la standardizzazione dei dati, che viene eseguita automaticamente dalla funzione.

Con la successiva funzione fviz_cluster() è generato il grafico dei cluster (myclust$cluster) ottenuti con l'algoritmo k-medoids e contenuti nell'oggetto myclust.


Date le premesse riportate all'inizio abbiamo impostato 3 come numero dei gruppi (cluster) in cui classificare i dati allo scopo di separare (i) sani, (ii) carenza di ferro, (iii) beta-talassemia eterozigote. Consapevoli del fatto che data la casistica, la quantità e il tipo delle informazioni di cui disponiamo, le altre possibili e meno frequenti cause di alterazione dell'esame emocromocitometrico (e ve ne sono molte) rimarranno inestricabilmente sovrapposte tra loro e/o con qualcuno di questi tre gruppi (a causa dei vincoli imposti dalla informazione disponibile che è, come sempre, limitata).

3) Analisi delle distribuzioni dei dati nei cluster.
Eccoci arrivati al punto. Non ci basta avere, per ciascun cluster, l'indicazione dei soggetti (numerati in ordine progressivo in mydata) appartenenti a ciascun cluster. Vogliamo avere anche l'indicazione della corrispondenza tra i cluster e le distribuzioni dei risultati delle grandezze misurate. Lo facciamo in una nuova finestra grafica aperta con windows() associando a ciascun caso (record) della tabella newdata con la funzione cbind() il cluster di appartenenza myclust$clustering estratto dall'oggetto 'pam' myclust che contiene i risultati del clustering e che viene riportato aggiungendo una sesta colonna alla tabella.

#
# analisi delle distribuzioni dei dati nei cluster
#
windows() # apre e inizializza una nuova finestra grafica
newclust <- cbind(newdata, myclust$clustering) # riporta per ciascun caso il cluster di appartenenza
ggpairs(newclust, columns=1:5, aes(color=as.factor(myclust$clustering), alpha=0.5), title="Scatterplot e kernel density plot dei dati dei cluster") # scatterplot e kernel density plot dei dati nei cluster

Ora abbiamo la tabella che possiamo impiegare per generare il grafico della distribuzione dei dati dei cluster con la funzione ggpairs() che impiega gli argomenti:
newclust per indicare la tabella che contiene i dati;
1:5 per indicare che i dati da rappresentare sono contenuti nelle colonne da 1 a 5 (la sesta contiene il cluster di appartenenza);
as.factor() in quanto le variabili numeriche 1, 2 e 3 della colonna 6 che indicano il cluster di appartenenza devono essere trasformate in variabili fattore;
alpha=0.5 per rappresentare i colori con una trasparenza del 50%.

Da notare che al bisogno potete anche esportare la tabella newclust, che nelle prime cinque colonne contiene i dati e nella sesta il cluster di appartenenza come qui indicato 

> newclust
      gr   hb  mcv hb_a2 ferro myclust$clustering
1   4.90 13.3 82.8   1.8   106                  1
2   4.66 10.8 73.6   2.6   148                  1
3   5.43 11.5 66.5   4.8   104                  2
4   5.41 10.8 73.4   2.5    74                  3
..........
642 5.28 11.0 65.4   1.9    11                  3
643 4.03  7.2 55.0   1.9    21                  3

e salvarla sotto forma di file [2].

Ed ecco il grafico risultante.


La conclusione? 
1) l'analisi dei gruppi fornisce una sintesi nella quale le grandezze soggiacenti non sono più riconoscibili singolarmente in quanto le componenti principali sono una combinazione lineare di tutte le variabili originali (nel primo dei grafici la prima componente principale in ascisse è la variabile formata dalla combinazione lineare di tutte le variabili originali che spiega la maggior quantità di varianza, la seconda componente principale in ordinate è la variabile che spiega la maggior quantità di varianza in ciò che rimane una volta rimosso l'effetto della prima componente principale);
2) la distribuzione dei dati all'interno dei cluster fornisce una rappresentazione di dettaglio che consente di ricollegare questi ultimi con la distribuzione originaria delle variabili la cui combinazione ha dato loro origine, e consente di riconoscere come:
→ il cluster 1 (rosso) contiene i soggetti con emoglobina A2 e ferro normali;
→ il cluster 2 (verde) contiene i soggetti con emoglobina A2 aumentata; 
→ il cluster 3 (azzurro) contiene i soggetti con ferro diminuito.

Pur con distribuzioni che in parte si sovrappongono – un fatto determinato dalla incompletezza della informazione disponibile rispetto alla complessità dei casi – l'esempio illustra come:
→ il clustering fornisce una vista sintetica dell'informazione globale contenuta nei dati;
→ possiamo aggiungere all'analisi dei cluster una vista di dettaglio delle distribuzioni dei singoli dati all'interno dei cluster;
→ le due viste degli stessi dati si integrano sinergicamente l'una con l'altra. 


----------

[1] Fate click su clustering nelle Parole chiave.


sabato 21 dicembre 2024

Analisi della varianza a due fattori con replicati

L'analisi della varianza o ANOVA – denominazione tradizionalmente impiegata per indicare una serie di tecniche che, a dispetto del nome, consentono di effettuare un confronto globale tra più medie – è stata presentata e illustrata in tutti i suoi aspetti in due post ai quali si rimanda [1].

Qui impieghiamo lo stesso disegno sperimentale riportato per l'analisi della varianza a due fattori e cioè


ma questa volta ciascuna delle misure di produzione per macchina/operatore è stata ripetuta quattro volte al fine di migliorarne la stima. Così ad esempio per macchina i=1 operatore j=2 nel file di dati che impieghiamo oltre al valore singolo 45.7 riportato qui sopra nella tabella originaria abbiamo in aggiunta le misure 46.9, 49.1 e 45.2 (questi dati sono stati evidenziati in colore nei dati riportati qui sotto) e quindi in totale quattro misure replicate. Questo è il disegno sperimentale tipico della analisi della varianza a due fattori con replicati.

Per proseguire è necessario:
→ effettuare il download del file di dati anova2r.csv
→ salvare il file nella cartella C:\Rdati\

Per il file di dati trovate link e modalità di download alla pagina Dati, ma potete anche semplicemente copiare i dati riportati qui sotto aggiungendo un ↵ Invio al termine dell'ultima riga e salvarli in C:\Rdati\ in un file di testo denominato anova2r.csv (assicuratevi che il file sia effettivamente salvato con l'estensione .csv).

macchina;operatore;replicato;produzione
i1;j1;1;57.2
i1;j1;2;56.7
i1;j1;3;55.9
i1;j1;4;58.3
i1;j2;1;45.7
i1;j2;2;46.9
i1;j2;3;49.1
i1;j2;4;45.4
i1;j3;1;47.3
i1;j3;2;49.4
i1;j3;3;48.1
i1;j3;4;47.5
i1;j4;1;54.9
i1;j4;2;52.6
i1;j4;3;53.5
i1;j4;4;54.1
i1;j5;1;35.9
i1;j5;2;37.2
i1;j5;3;38.7
i1;j5;4;36.4
i2;j1;1;64.5
i2;j1;2;61.1
i2;j1;3;63.9
i2;j1;4;64.7
i2;j2;1;52.4
i2;j2;2;55.3
i2;j2;3;57.2
i2;j2;4;53.9
i2;j3;1;54.1
i2;j3;2;56.2
i2;j3;3;52.3
i2;j3;4;53.8
i2;j4;1;57.5
i2;j4;2;55.9
i2;j4;3;56.3
i2;j4;4;58.8
i2;j5;1;52.5
i2;j5;2;50.3
i2;j5;3;51.4
i2;j5;4;53.3
i3;j1;1;56.6
i3;j1;2;59.7
i3;j1;3;56.3
i3;j1;4;56.5
i3;j2;1;51.6
i3;j2;2;50.3
i3;j2;3;47.8
i3;j2;4;52.6
i3;j3;1;49.5
i3;j3;2;52.7
i3;j3;3;49.1
i3;j3;4;47.7
i3;j4;1;56.9
i3;j4;2;58.5
i3;j4;3;57.1
i3;j4;4;55.2
i3;j5;1;44.2
i3;j5;2;46.7
i3;j5;3;43.9
i3;j5;4;42.6

Per l'analisi della varianza anche in questo caso viene impiegata la funzione aov() impiegata per le altre [1] specificando questa volta che la variabilità deve essere decomposta in variabilità dovuta alla macchina, dovuta all'operatore e dovuta ai replicati eseguiti. 

Copiate e incollate nella Console di R questo script e premete ↵ Invio.

# ANOVA analisi della varianza a due fattori con replicati
#
mydata <- read.table("c:/Rdati/anova2r.csv", header=TRUE, sep=";", dec=".") # importa i dati 
#
anova2r <- aov(produzione~macchina+operatore+replicato, data=mydata) # calcola la variabilità tra macchine, operatori e replicati
#
summary(anova2r) # mostra i risultati
#

Il risultato della ANOVA

> summary(anova2r) # mostra i risultati
            Df Sum Sq Mean Sq F value   Pr(>F)    
macchina     2  602.8   301.4  54.792 1.58e-13 ***
operatore    4 1552.2   388.1  70.544  < 2e-16 ***
replicato    1    0.3     0.3   0.048    0.827    
Residuals   52  286.0     5.5                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

ci dice che le differenze di produzione tra le tre macchine e le differenze di produzione tra i cinque operatori sono significative, mentre le misure di produzione replicate all'interno della stessa coppia macchina/operatore non differiscono significativamente (p=0.827).

Possiamo avere anche un riscontro grafico dei dati, copiate e incollate nella Console di R queste righe e premete ↵ Invio.

# traccia boxplot per macchina e operatore
#
boxplot(produzione~macchina+operatore, data=mydata) 
#

(per mostrare sulle ascisse i nomi di tutte le variabili, dopo avere generato il grafico ho "afferrato" con il mouse il lato sinistro della finestra per allargarla)


A questo punto manca però la verifica che i dati siano conformi ai due assunti alla base dell'ANOVA, che abbiano cioè:
→ una distribuzione normale (gaussiana);
→ varianze omogenee;
due esigenze che abbiamo già illustrato nei precedenti post sulla ANOVA [1].

Per valutare la normalità (gaussianità) dei dati impieghiamo il test di normalità di Shapiro-Wilk, copiate queste ultime righe, incollatele nella Console di R e premete ↵ Invio:

# ANOVA verifica della normalità delle distribuzioni
#
mac <- split(mydata$produzione, mydata$macchina) # estrae e separa i dati di produzione per macchina
#
sapply(mac, shapiro.test) # verifica se i dati delle macchine sono distribuiti in modo gaussiano
#

La funzione split() estrae dall'oggetto mydata i dati di produzione (mydata$produzione) per ciascuna macchina (mydata$macchina) e li riporta, separatamente, nell'oggetto mac. Se digitate

mac 

potete vedere come sono organizzati i dati estratti per le tre macchine.

> mac
$i1
 [1] 57.2 56.7 55.9 58.3 45.7 46.9 49.1 45.4 47.3 49.4 48.1 47.5 54.9 52.6 53.5
[16] 54.1 35.9 37.2 38.7 36.4

$i2
 [1] 64.5 61.1 63.9 64.7 52.4 55.3 57.2 53.9 54.1 56.2 52.3 53.8 57.5 55.9 56.3
[16] 58.8 52.5 50.3 51.4 53.3

$i3
 [1] 56.6 59.7 56.3 56.5 51.6 50.3 47.8 52.6 49.5 52.7 49.1 47.7 56.9 58.5 57.1
[16] 55.2 44.2 46.7 43.9 42.6

A questo punto con la funzione sapply() il test di Shapiro-Wilk viene applicato automaticamente ai dati delle tre macchine.

> sapply(mac, shapiro.test) # verifica se i dati delle macchine sono distribuiti in modo gaussiano
          i1                            i2                           
statistic 0.9202174                     0.9052156                    
p.value   0.1000444                     0.05170547                   
method    "Shapiro-Wilk normality test" "Shapiro-Wilk normality test"
data.name "X[[i]]"                      "X[[i]]"                     
          i3                           
statistic 0.9449654                    
p.value   0.2970447                    
method    "Shapiro-Wilk normality test"
data.name "X[[i]]"   

I valori di p ci dicono che le distribuzioni possono essere considerate gaussiane, quindi questo assunto dell'ANOVA è rispettato. 

Ora valutiamo l'omogeneità delle varianze impiegando il test di Levene, copiate queste righe, incollatele nella Console di R e premete ↵ Invio:

# Test di Levene per l'omogeneità tra varianze
#
library(car) # carica il pacchetto necessario per eseguire il test
#
leveneTest(produzione~macchina, data=mydata) # verifica se le varianze risultano omogenee
#

Dopo avere caricato il pacchetto car il test di Levene viene eseguito impiegando la funzione leveneTest() sui dati di produzione per ciascuna delle tre macchine (produzione~macchina). Il messaggio di avvertimento può essere ignorato in quanto ci dice semplicemente che la funzione ha trasformato automaticamente la nostra variabile in una variabile "fattore".

> leveneTest(produzione~macchina, data=mydata) # verifica se le varianze risultano omogenee
Levene's Test for Homogeneity of Variance (center = median)
      Df F value  Pr(>F)  
group  2  2.4955 0.09142 .
      57                  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Messaggio di avvertimento:
In leveneTest.default(y = y, group = group, ...) : group coerced to factor.

Il valor di p (0.09142) ci dice che le varianze sono omogenee, quindi anche questo assunto è rispettato.

La conclusione: stabilito che per i dati di produzione per macchina i due requisiti del modello statistico alla base dell'ANOVA sono rispettati, possiamo accettare il risultato della analisi della varianza a due fattori con replicati che ci dice che esiste una differenza statisticamente significativa tra le medie di produzione delle tre macchine (p=1.58e-13).

Sono lasciati come esercizio l'applicazione del test di normalità e del test di omogeneità tra varianze ai dati di produzione per operatore e le relative conclusioni, mentre per questo specifico disegno della ANOVA valgono, identiche, le considerazioni generali riportate nei due post precedenti, ai quali si rimanda [1]


----------


martedì 3 dicembre 2024

Effettuare una interpolazione lineare

Data una serie di valori su un piano cartesiano, il valore della variabile dipendente y corrispondente ad uno specifico valore della variabile indipendente x può essere ricavato mediante:
interpolazione quando può essere calcolato a partire dalla sua posizione tra due dati adiacenti;
approssimazione quando può essere calcolato dalla intersezione con una funzione che approssima i dati e ne fornisce una appropriata descrizione;
→ estrapolazione quando, nell'uno e nell'altro caso, si assume che possa essere calcolato anche al di fuori dell'intervallo dei dati osservati.


L'approssimazione è ampiamente utilizzata in statistica, come ad esempio nel caso del metodo dei minimi quadrati, che consente di calcolare la funzione (retta o polinomio) che, sotto una serie di ipotesi [1], "meglio" approssima i dati. In ogni caso la x della quale si cerca la y corrispondente deve cadere nell'ambito (range) dei valori osservati perché il calcolo mediante la funzione approssimante possa essere ritenuto affidabile.

L'estrapolazione cioè l'estensione delle conclusioni al di la dei valori osservati è un'operazione da proscrivere, a meno che si disponga di un modello ben consolidato. Così ad esempio le leggi della meccanica celeste applicate a una sequenza di posizioni recenti di un asteroide possono consentire una estrapolazione della sua posizione in un tempo futuro, ma i casi di leggi deterministiche di questo genere sono limitati e collegati a campi specifici molto particolari.

Qui vediamo il caso più semplice, la interpolazione lineare, che assume che i due punti adiacenti alla x della quale si cerca la y corrispondente possano essere collegati da un segmento di retta. Nel caso di una curva, più i due punti adiacenti sono ravvicinati, più corto è il segmento di retta, più accurata è l'interpolazione.

Non sono richiesti pacchetti aggiuntivi, in quanto tutte le funzioni che impieghiamo sono  incluse nell'installazione base di ROra copiate e incollate nella Console di R questa prima parte dello script e premete ↵ Invio.

# INTERPOLAZIONE LINEARE
#
x <- c(1.21, 1.32, 1.42, 1.53, 1.64, 1.75, 1.85, 1.96, 2.07, 2.18, 2.28, 2.39, 2.50, 2.61, 2.72, 2.82, 2.93, 3.04, 3.15, 3.25, 3.36, 3.47, 3.58, 3.68, 3.79) # valori in ascisse
y <- c(46.86, 47.08, 47.26, 47.42, 47.48, 47.46, 47.37, 47.22, 46.92, 46.61, 46.29, 45.98, 45.64, 45.29, 44.95, 44.64, 44.38, 44.15, 43.98, 43.92, 43.90, 43.93, 43.97, 44.09, 44.26) # valori in ordinate
#
plot(x, y, type="l") # traccia il grafico della funzione
#

Le prime due righe riportano le coppie di coordinate x,y dei dati osservati. Questo è il grafico risultante, tracciato nella terza riga con la funzione plot() che impiega per tutti gli argomenti i valori di default, specificando solamente che i punti devono essere collegati con una linea ("l") [2].


Ora supponiamo di avere per la x i valori 1.3, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.7 e di volere calcolare mediante interpolazione lineare i valori della y corrispondenti.

Per farlo copiate e incollate nella Console di R queste due altre righe di codice e premete ↵ Invio.

#
interp <- approx(x, y, xout=c(1.3, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.7), ties="ordered") # interpola una serie di valori specificati
#
round(cbind(interp$x, interp$y), digits=2) # mostra i risultati dell'interpolazione
#

L'interpolazione viene effettuata con la funzione approx() impiegando come argomenti:
→ le ascisse x dei punti che descrivono la funzione;
→ le ordinate y dei punti che descrivono la funzione;
→ le ascisse xout dei punti da interpolare; 
→ l'indicazione "ordered" che indica che i dati di partenza sono già ordinati.

I risultati dell'approssimazione sono salvati nell'oggetto interp dal quale sono tratti i valori delle ascisse inseriti (interp$x) e i valori delle ordinate calcolati per ciascuno di essi (interp$y). Questi valori sono combinati in una tabella con la funzione cbind(), sono arrotondati con la funzione round() a due decimali (digits=2) e mostrati come segue:

> round(cbind(interp$x, interp$y), digits=2) # mostra i risultati dell'interpolazione
      [,1]  [,2]
 [1,]  1.3 47.04
 [2,]  1.4 47.22
 [3,]  1.6 47.46
 [4,]  1.8 47.42
 [5,]  2.0 47.11
 [6,]  2.2 46.55
 [7,]  2.4 45.95
 [8,]  2.6 45.32
 [9,]  2.8 44.70
[10,]  3.0 44.23
[11,]  3.2 43.95
[12,]  3.4 43.91
[13,]  3.6 43.99
[14,]  3.7 44.12

Con questa riga di codice potete, per controllo, sovrapporre alla curva originaria i punti interpolati.

#
points(interp$x, interp$y, pch=3, col="red") # riporta sul grafico i punti interpolati
#

Come si vede i punti interpolati cadono tutti sulla curva e indicano una adeguata approssimazione. 


Per interpolare un singolo valore e riportarlo sul grafico il codice da impiegare risulta ovviamente più conciso come in questo esempio.

#
val <- approx(x, y, xout=1.7) # interpola un singolo valore
#
points(val, pch=4, col="blue") # riporta sul grafico il punto interpolato
#

Per visualizzare il risultato numerico di questa ulteriore interpolazione è sufficiente nella Console di R digitare

val 

che mostra il contenuto dell'oggetto, rappresentato dal valore della x inserita e da quello della y risultante:

> val
$x
[1] 1.7

$y
[1] 47.46909


----------


[2] Digitare help(plot) nella Console di R per la documentazione della funzione.