Step 0. get done w/o extending
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.0 ✔ readr 2.1.4
## ✔ forcats 1.0.0 ✔ stringr 1.5.0
## ✔ ggplot2 3.4.1 ✔ tibble 3.2.0
## ✔ lubridate 1.9.2 ✔ tidyr 1.3.0
## ✔ purrr 1.0.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
stdz <- function(x){
var_mean <- mean(x)
var_sd <- sd(x)
(x-var_mean)/var_sd
}
cars %>%
mutate(x = stdz(speed), y = stdz(dist)) ->
prep
lm(y~x, data = prep) ->
model
prep %>%
mutate(y0 = y) %>%
mutate(y = model$fitted.values) %>%
mutate(ymin = model$fitted.values) %>%
mutate(yend = y0) %>%
mutate(ymax = y0) %>%
mutate(xmin = x) %>%
mutate(xend = x) %>%
mutate(xmax = x + ( ymax- ymin)) %>%
ggplot()+
aes(x, y, xmin = xmin, ymin = ymin, xmax = xmax, ymax = ymax) +
geom_point() +
coord_equal() +
geom_rect()
Step 1. Compute group
compute_group_lm_fitted<- function(data, scales){
model<-lm(formula= y ~ x, data = data)
data %>%
mutate(y0 = y) %>%
mutate(y = model$fitted.values) %>%
mutate(ymin = model$fitted.values) %>%
mutate(yend = y0) %>%
mutate(ymax = y0) %>%
mutate(xmin = x) %>%
mutate(xend = x) %>%
mutate(xmax = x + ( ymax- ymin))
}
# test out the function
cars %>%
# rename to explicitly state the x and y inputs
rename(x = speed, y = dist) %>%
compute_group_lm_fitted()
## x y y0 ymin yend ymax xmin xend xmax
## 1 4 -1.849460 2 -1.849460 2 2 4 4 7.8494599
## 2 4 -1.849460 10 -1.849460 10 10 4 4 15.8494599
## 3 7 9.947766 4 9.947766 4 4 7 7 1.0522336
## 4 7 9.947766 22 9.947766 22 22 7 7 19.0522336
## 5 8 13.880175 16 13.880175 16 16 8 8 10.1198248
## 6 9 17.812584 10 17.812584 10 10 9 9 1.1874161
## 7 10 21.744993 18 21.744993 18 18 10 10 6.2550073
## 8 10 21.744993 26 21.744993 26 26 10 10 14.2550073
## 9 10 21.744993 34 21.744993 34 34 10 10 22.2550073
## 10 11 25.677401 17 25.677401 17 17 11 11 2.3225985
## 11 11 25.677401 28 25.677401 28 28 11 11 13.3225985
## 12 12 29.609810 14 29.609810 14 14 12 12 -3.6098102
## 13 12 29.609810 20 29.609810 20 20 12 12 2.3901898
## 14 12 29.609810 24 29.609810 24 24 12 12 6.3901898
## 15 12 29.609810 28 29.609810 28 28 12 12 10.3901898
## 16 13 33.542219 26 33.542219 26 26 13 13 5.4577810
## 17 13 33.542219 34 33.542219 34 34 13 13 13.4577810
## 18 13 33.542219 34 33.542219 34 34 13 13 13.4577810
## 19 13 33.542219 46 33.542219 46 46 13 13 25.4577810
## 20 14 37.474628 26 37.474628 26 26 14 14 2.5253723
## 21 14 37.474628 36 37.474628 36 36 14 14 12.5253723
## 22 14 37.474628 60 37.474628 60 60 14 14 36.5253723
## 23 14 37.474628 80 37.474628 80 80 14 14 56.5253723
## 24 15 41.407036 20 41.407036 20 20 15 15 -6.4070365
## 25 15 41.407036 26 41.407036 26 26 15 15 -0.4070365
## 26 15 41.407036 54 41.407036 54 54 15 15 27.5929635
## 27 16 45.339445 32 45.339445 32 32 16 16 2.6605547
## 28 16 45.339445 40 45.339445 40 40 16 16 10.6605547
## 29 17 49.271854 32 49.271854 32 32 17 17 -0.2718540
## 30 17 49.271854 40 49.271854 40 40 17 17 7.7281460
## 31 17 49.271854 50 49.271854 50 50 17 17 17.7281460
## 32 18 53.204263 42 53.204263 42 42 18 18 6.7957372
## 33 18 53.204263 56 53.204263 56 56 18 18 20.7957372
## 34 18 53.204263 76 53.204263 76 76 18 18 40.7957372
## 35 18 53.204263 84 53.204263 84 84 18 18 48.7957372
## 36 19 57.136672 36 57.136672 36 36 19 19 -2.1366715
## 37 19 57.136672 46 57.136672 46 46 19 19 7.8633285
## 38 19 57.136672 68 57.136672 68 68 19 19 29.8633285
## 39 20 61.069080 32 61.069080 32 32 20 20 -9.0690803
## 40 20 61.069080 48 61.069080 48 48 20 20 6.9309197
## 41 20 61.069080 52 61.069080 52 52 20 20 10.9309197
## 42 20 61.069080 56 61.069080 56 56 20 20 14.9309197
## 43 20 61.069080 64 61.069080 64 64 20 20 22.9309197
## 44 22 68.933898 66 68.933898 66 66 22 22 19.0661022
## 45 23 72.866307 54 72.866307 54 54 23 23 4.1336934
## 46 24 76.798715 70 76.798715 70 70 24 24 17.2012847
## 47 24 76.798715 92 76.798715 92 92 24 24 39.2012847
## 48 24 76.798715 93 76.798715 93 93 24 24 40.2012847
## 49 24 76.798715 120 76.798715 120 120 24 24 67.2012847
## 50 25 80.731124 85 80.731124 85 85 25 25 29.2688759
Step 2. pass to ggproto
StatLmFitted<-ggplot2::ggproto(`_class` = "StatLmFitted",
`_inherit` = ggplot2::Stat,
required_aes = c("x", "y"),
compute_group = compute_group_lm_fitted)
Step 3. pass to geom function.
geom_lm_residual_sq <- function(mapping = NULL, data = NULL,
position = "identity", na.rm = FALSE,
show.legend = NA,
inherit.aes = TRUE, ...) {
ggplot2::layer(
stat = StatLmFitted, # proto object from step 2
geom = ggplot2::GeomRect, # inherit other behavior
data = data,
mapping = mapping,
position = position,
show.legend = show.legend,
inherit.aes = inherit.aes,
params = list(na.rm = na.rm, ...)
)
}
Step 4. Enjoy
library(ggxmean)
# not a great result
library(tidyverse)
ggplot(cars) +
aes(speed, dist) +
geom_point() +
geom_lm() +
geom_lm_fitted(color = "blue") +
geom_lm_residual_sq(alpha = .2)
# better
last_plot() +
coord_equal()
# best
last_plot() +
aes(stdz(speed), stdz(dist))
# coord_sd_equal() Could this be a useful thing to this problem or another problem
look at small data
ggplot(anscombe) +
aes(x = x1, y = y1) +
geom_point() +
geom_lm() +
geom_lm_fitted(color = "blue") +
geom_lm_residual_sq(alpha = .2)
last_plot() +
coord_equal()
last_plot() +
aes(stdz(x1), stdz(y1))