2010-04-14 7 views
15

Me interesa hacer una gráfica con una línea de regresión de mínimos cuadrados y segmentos de línea que conecten los puntos de datos a la línea de regresión como se ilustra aquí en el gráfico denominado compensaciones perpendiculares: http://mathworld.wolfram.com/LeastSquaresFitting.html alt text http://mathworld.wolfram.com/images/eps-gif/LeastSquaresOffsets_1000.gifGraficar desplazamientos perpendiculares en un gráfico de regresión de mínimos cuadrados en R

he la trama y la regresión hecho aquí:

## Dataset from http://www.apsnet.org/education/advancedplantpath/topics/RModules/doc1/04_Linear_regression.html 

## Disease severity as a function of temperature 

# Response variable, disease severity 
diseasesev<-c(1.9,3.1,3.3,4.8,5.3,6.1,6.4,7.6,9.8,12.4) 

# Predictor variable, (Centigrade) 
temperature<-c(2,1,5,5,20,20,23,10,30,25) 

## For convenience, the data may be formatted into a dataframe 
severity <- as.data.frame(cbind(diseasesev,temperature)) 

## Fit a linear model for the data and summarize the output from function lm() 
severity.lm <- lm(diseasesev~temperature,data=severity) 

# Take a look at the data 
plot(
diseasesev~temperature, 
     data=severity, 
     xlab="Temperature", 
     ylab="% Disease Severity", 
     pch=16, 
     pty="s", 
     xlim=c(0,30), 
     ylim=c(0,30) 
) 
abline(severity.lm,lty=1) 
title(main="Graph of % Disease Severity vs Temperature") 

¿Debo usar algún tipo de bucle y segmentos http://www.iiap.res.in/astrostat/School07/R/html/graphics/html/segments.html hacer los desplazamientos perpendiculares? ¿Hay una manera más eficiente? Por favor dé un ejemplo si es posible.

Respuesta

16

Primero necesita averiguar las coordenadas para la base de los segmentos perpendiculares, luego llame a la función segments que puede tomar vectores de coordenadas como entradas (sin necesidad de un bucle).

perp.segment.coord <- function(x0, y0, lm.mod){ 
#finds endpoint for a perpendicular segment from the point (x0,y0) to the line 
# defined by lm.mod as y=a+b*x 
    a <- coef(lm.mod)[1] #intercept 
    b <- coef(lm.mod)[2] #slope 
    x1 <- (x0+b*y0-a*b)/(1+b^2) 
    y1 <- a + b*x1 
    list(x0=x0, y0=y0, x1=x1, y1=y1) 
} 

Ahora acaba de llamar segmentos:

ss <- perp.segment.coord(temperature, diseasesev, severity.lm) 
do.call(segments, ss) 
#which is the same as: 
segments(x0=ss$x0, x1=ss$x1, y0=ss$y0, y1=ss$y1) 

Tenga en cuenta que los resultados no se verán perpendicular a menos que asegurarse de que el X-unidad y la unidad y de la trama tienen la misma longitud aparente (escalas isométricos) Puede hacerlo utilizando pty="s" para obtener un gráfico cuadrado y establecer xlim y ylim en el mismo rango.

+0

Perfecto, gracias. –

Cuestiones relacionadas