Tengo un conjunto de datos y una trama como la siguiente:

rowid <- (1:100)
intercept <- (200:299)
df <- data.frame(rowid, intercept)

ggplot(df, aes(x=rowid, y=intercept, color=intercept)) + geom_point() 
+ scale_colour_gradient2(low="red", high="darkgreen", mid = "yellow", midpoint = 250) 
+ geom_smooth(method='lm', color = 'black')

Mi conjunto de datos y gráfico tienen muchos más datos, por lo que se ve así: r plot

Pregunta:

¿Cómo consigo que los puntos por encima de la línea de regresión tengan un color determinado (verde), los puntos por debajo de la línea de regresión tengan un color determinado (rojo) y todos los demás puntos tengan un color determinado (amarillo)?

Además de eso (si es posible), me gustaría agregar otra etiqueta de columna Grade que muestre los puntos de la línea de regresión mencionados arriba como "A", todos los demás puntos como "C" y debajo de la línea de regresión listada como "F".

0
Sunny 25 jun. 2020 a las 20:44

2 respuestas

La mejor respuesta

Como primer ejemplo (sin la posibilidad de que un punto se encuentre directamente EN la línea de regresión): Calcule el valor ajustado para cada valor de x, ajustando un modelo lineal antes del trazado real. Después de eso, simplemente puede vincular una columna booleana a su marco de datos, especificando si el valor predicho es menor o mayor que el verdadero y.

library(ggplot2)

rowid <- (1:1000)
intercept <- rnorm(1000, 0, 1)*rowid+1:1000
mod <- lm(intercept ~ rowid)
fitted <- mod$fitted.values
smaller <- intercept < fitted
df <- data.frame(rowid, intercept, smaller)


ggplot(df, aes(x=rowid, y=intercept, color=as.factor(smaller))) + 
  geom_point()+
  geom_smooth(method='lm', color = 'black')+
  scale_color_manual(values = c("green", "yellow"))

enter image description here

Habiendo leído la última oración de su publicación solo ahora, un enfoque para introducir una columna de factor de tres niveles con los niveles "A", "F" y "C" y trazarlos en consecuencia después. Introduje 200 puntos, donde el valor ajustado y el verdadero y son iguales:

library(ggplot2)

rowid <- (1:1000)
intercept <- rnorm(1000, 0, 1)*rowid+1:1000
mod <- lm(intercept ~ rowid)
fitted <- mod$fitted.values
#demonstration: add some points, where fitted value equals the true value
sample_points <- sample(1:1000, 200, replace = FALSE)

intercept[sample_points] <- fitted[sample_points]

#construct three level factor, with a chain of ifelse:
grade <- as.factor(ifelse(intercept < fitted, "F", ifelse(intercept == fitted, "C", "A")))
df <- data.frame(rowid, intercept, grade)

ggplot(df, aes(x=rowid, y=intercept, color=grade)) + 
  geom_point()+
  geom_smooth(method='lm', color = 'black')+
  scale_color_manual(values = c("green", "yellow", "red"))
3
EconStudent_2611 25 jun. 2020 a las 19:04

Querrá volver a implementar lo que geom_smooth() está haciendo con algo como

m = lm(intercept~rowid, data=df) # note that format is y~x

Lo que te dará pendiente e intercepción bajo m$coefficients. Puedes verificar esto con

ggplot(df, aes(x=rowid, y=intercept, color=intercept)) + geom_point() +
    scale_colour_gradient2(low="red", high="darkgreen", mid = "yellow", midpoint = 250) +
    # geom_smooth(method='lm', color = 'black') + 
    geom_abline(slope = m$coefficients[2], intercept = m$coefficients[1])

Que reemplaza la línea geom_smooth()

Luego puede crear una nueva columna en df que le indica si está por encima / debajo de la línea o simplemente usa m$residuals. Ejemplo de la primera opción sería algo así como

df = cbind(df, up_down = if_else(
    df$intercept > df$row_id*m$coefficients[2]+m$coefficients[1],
    "above", 
    "below")
) # pseudocode
0
yingw 25 jun. 2020 a las 18:16