Loading final model

This uses data prior to the first exam only.

library(tidyverse)
library(car)
library(nlme)
library(haven)
library(tibble)

recode_df <- read_csv('/Users/joshuarosenberg/Dropbox/1_Research/Engagement/yday.csv')

recode <- filter(recode_df, yday <= 48)

recode <- mutate(recode, wave = case_when(
  yday <= 4 ~ 12,
  yday > 4 & yday <= 8 ~ 11,
  yday > 8 & yday <= 12 ~ 10,
  yday > 12 & yday <= 16 ~ 9,
  yday > 16 & yday <= 20 ~ 8,
  yday > 20 & yday <= 24 ~ 7,
  yday > 24 & yday <= 28 ~ 6,
  yday > 28 & yday <= 32 ~ 5,
  yday > 32 & yday <= 36 ~ 4,
  yday > 36 & yday <= 40 ~ 3,
  yday > 40 & yday <= 44 ~ 2,
  yday > 44 & yday <= 48 ~ 1
))

recode <- recode %>% 
  group_by(student_ID, wave) %>%
  summarize(mean_time_watched_minutes = sum(time_watched_minutes, na.rm = T))

recode_df %>% 
  group_by(yday) %>% 
  summarize(sum_tw = sum(time_watched_minutes)) %>% 
  ggplot(aes(x = yday, y = sum_tw)) +
  geom_point() +
  geom_line()

# library(lme4)
# 
# m1 <- lmer(time_watched_minutes ~ wave + I(wave ^ 2) +
#              (wave + I(wave ^ 2) | student_ID), data = recode,
#            control = lmerControl(optimizer="bobyqa", optCtrl = list(maxfun = 100000)))

recode.grouped <- groupedData(mean_time_watched_minutes ~ wave|student_ID, data = recode, order.groups = F)

ctrl <- lmeControl(opt='optim', maxIter=1e8, msMaxIter = 1e8)

model5.1a <- lme(mean_time_watched_minutes ~ wave,
                 random = ~ wave,, method = "REML",
                 data = recode.grouped, na.action = na.omit, control = ctrl)

# model5.1b <- lme(time_watched_minutes ~ wave + I(wave^2) + I(wave ^ 3),
#           random = ~ wave + I(wave^2) + I(wave ^ 3), method = "REML",
#           data = recode.grouped, na.action = na.omit, control = ctrl)
# 
# model5.1bb <- lme(time_watched_minutes ~ wave + I(wave^2) + I(wave ^ 3),
#           random = ~ wave + I(wave^2) + I(wave ^ 3), method = "REML",
#           data = recode.grouped, na.action = na.omit, control = ctrl)

# pick a model

model5.1 <- model5.1a

# model5.1 <- lme(View~TimeN_tilexam + I(TimeN_tilexam^2) + I(TimeN_tilexam^3) 
#                 + I(TimeN_tilexam^4) + I(TimeN_tilexam^5),
#                 random = ~TimeN_tilexam , method = "REML", 
#                 data = recode.grouped, na.action=na.omit)
# summary(model5.1)


# model1a <- lme(View ~ TimeN_tilexam + I(TimeN_tilexam^2),
#                random = ~TimeN_tilexam + I(TimeN_tilexam^2), method = "REML", 
#                data = recode.grouped, na.action=na.omit, control = ctrl)
# summary(model1a)
# 
# model5.1 <- model1b

Processing other data

broom::glance(model5.1)
##      sigma    logLik      AIC      BIC deviance
## 1 31.09569 -15968.07 31948.14 31984.68       NA
dff <- rownames_to_column(random.effects(model5.1))
dff <- tbl_df(dff)

names(dff) <- c("ID", "intercept", "linear_slope")

dff <- mutate(dff,
              intercept = intercept + fixed.effects(model5.1)[1],
              linear_slope = linear_slope + fixed.effects(model5.1)[2])

# names(dff) <- c("ID", "intercept", "linear_slope", "quadratic_slope", "cubic_slope")
# 
# dff <- mutate(dff,
#               intercept = intercept + 17.52,
#               linear_slope = linear_slope - 6.61,
#               quadratic_slope = quadratic_slope + .979,
#               cubic_slope = cubic_slope - .045)

dff$ID <- as.integer(dff$ID)

df_coef <- tbl_df(coef(model5.1))

names(df_coef) <- c("unadjusted_intercept", "unadjusted_linear_slope")

# names(df_coef) <- c("unadjusted_intercept", "unadjusted_linear_slope", "quadratic_slope", "cubic_slope")

df_coef <- df_coef %>% rownames_to_column() %>% rename(ID = rowname) %>% mutate(ID = as.integer(ID))

dff <- left_join(dff, df_coef)

grades_data <- read_sav("~/Dropbox/1_research/Engagement/data/all_three_semesters.sav")
grades_data <- select(grades_data, ID, contains("Exam"), FinalGrade)
grades_data$ID <- as.integer(grades_data$ID)

IDs_data <- read_csv("~/Dropbox/1_Research/Engagement/Archive/ss15_key.csv")
IDs_data <- select(IDs_data, ID, username = Username)

demographic_data <- left_join(IDs_data, grades_data, by = "ID")

df <- left_join(dff, demographic_data)

all_three_semesters <- read_sav("~/Dropbox/1_Research/Engagement/Data/all_three_semesters.sav")

all_three_semesters$ID <- as.integer(all_three_semesters$ID)

dfm <- left_join(df, all_three_semesters, by = "ID")

dfm$T1Q003 <- ifelse(dfm$T1Q003 == 1, 5,
                     ifelse(dfm$T1Q003 == 2, 4,
                            ifelse(dfm$T1Q003 == 4, 2,
                                   ifelse(dfm$T1Q003 == 5, 1, NA))))

dfm$T1Q017 <- ifelse(dfm$T1Q017 == 1, 5,
                     ifelse(dfm$T1Q017 == 2, 4,
                            ifelse(dfm$T1Q017 == 4, 2,
                                   ifelse(dfm$T1Q017 == 5, 1, NA))))

dfm$T1Q042 <- ifelse(dfm$T1Q042 == 1, 5,
                     ifelse(dfm$T1Q042 == 2, 4,
                            ifelse(dfm$T1Q042 == 4, 2,
                                   ifelse(dfm$T1Q042 == 5, 1, NA))))

dfm$T1Q034 <- ifelse(dfm$T1Q034 == 1, 5,
                     ifelse(dfm$T1Q034 == 2, 4,
                            ifelse(dfm$T1Q034 == 4, 2,
                                   ifelse(dfm$T1Q034 == 5, 1, NA))))

dfm$T1Q025 <- ifelse(dfm$T1Q025 == 1, 5,
                     ifelse(dfm$T1Q025 == 2, 4,
                            ifelse(dfm$T1Q025 == 4, 2,
                                   ifelse(dfm$T1Q025 == 5, 1, NA))))

dfm$cost_value <- jmRtools::composite_mean_maker(dfm, T1Q003, T1Q017, T1Q042, T1Q034, T1Q025)

dfm$perceived_competence <- jmRtools::composite_mean_maker(dfm, T1Q016, T1Q007, T1Q028, T1Q035, T1Q022)

dfm$utility_value <- jmRtools::composite_mean_maker(dfm, T1Q038, T1Q014, T1Q026, T1Q005, T1Q043)

dfm$interest_value <- jmRtools::composite_mean_maker(dfm, T1Q036, T1Q019, T1Q001, T1Q032, T1Q041)

dfm$attainment_value <- jmRtools::composite_mean_maker(dfm, T1Q024, T1Q009, T1Q045, T1Q030, T1Q012)

dfm$task_value <- jmRtools::composite_mean_maker(dfm, T1Q038, T1Q014, T1Q026, T1Q005, T1Q043, T1Q036, T1Q019, T1Q001, T1Q032, T1Q041, T1Q024, T1Q009, T1Q045, T1Q030, T1Q012)

dfm$mastery_approach <- jmRtools::composite_mean_maker(dfm, T1Q003, T1Q012, T1Q020, T1Q024, T1Q027)

dfm$mastery_avoid <- jmRtools::composite_mean_maker(dfm, T1Q036, T1Q015, T1Q006, T1Q022)

dfm$performance_approach <- jmRtools::composite_mean_maker(dfm, T1Q034, T1Q008, T1Q033, T1Q025, T1Q039)

dfm$performance_avoid <- jmRtools::composite_mean_maker(dfm, T1Q041, T1Q030, T1Q018, T1Q004)

dfm <- dfm %>% select(ID, cost_value, perceived_competence, utility_value, final_grade = Percent_FinalGrade, intercept, linear_slope, task_value, mastery_approach, mastery_avoid, performance_approach, performance_avoid)

# dfm <- dfm %>% select(ID, cost_value, perceived_competence, utility_value, final_grade = Percent_FinalGrade, intercept, linear_slope, quadratic_slope, cubic_slope, task_value)

Profiles

library(prcr)
x <- create_profiles(dfm, mastery_approach, performance_approach, performance_avoid, n_profiles=3, to_center=T, to_scale=T)
plot(x)

Overall model

For some reason, we get a different overall model when we use the population-level (not ID, i.e. not student but overall) predictions. There’s also some code for using the equation.

Some other representations of models

Here’s one using the student-level predictions.

In these models, the intercepts and slopes are adjusted based on the random effects for those terms.

Look out, lots going on.

dfm_b <- dfm

predictions <- predict(model5.1, recode.grouped, level = 1) 
df_for_plot <- as.tibble(bind_cols(as.data.frame(recode.grouped), predictions = predictions))
df_for_plot$student_ID <- as.integer(as.character(df_for_plot$student_ID))

# x <- 0:5
# dat <- data.frame(x,
#                   y = 8.15 - (15.12 * x) + (14.78 * (x ^ 2)) - (6.12 * (x ^ 3)) + (1.15 * (x ^ 4)) - (.08 * (x ^ 5)))
# 
# f <- function(x) 8.15 - (15.12 * x) + (14.78 * (x ^ 2)) - (6.12 * (x ^ 3)) + (1.15 * (x ^ 4)) - (.08 * (x ^ 5))

# ggplot(dat, aes(x,y)) +
#   stat_function(fun=f, colour="black") +
#   hrbrthemes::theme_ipsum() +
#   ylab("Mean Minutes Watched / Day") +
#   xlab("Weeks Before Exam")

dfm <- rename(df, student_ID = ID)

dfm$final_grade <- as.vector(dfm$final_grade)
## Warning: Unknown or uninitialised column: 'final_grade'.
df_for_plot %>% 
  left_join(dfm) %>% 
  filter(!is.na(FinalGrade) & !is.na(student_ID)) %>% 
  select(student_ID, wave, predictions) %>% 
  group_by(student_ID, wave) %>% 
  summarize(predictions = sum(predictions, na.rm = T)) %>% 
  spread(wave, predictions) %>% 
  gather(key, val, -student_ID) %>% 
  ungroup() %>% 
  mutate(ID = as.factor(student_ID),
         key = factor(key, levels = 0:12)) %>% 
  ggplot(aes(x = key, y = val, group = ID)) +
  geom_point() +
  geom_line() +
  viridis::scale_color_viridis() +
  hrbrthemes::theme_ipsum() +
  xlab("Wave") +
  ylab("Mean Minutes Viewed")
## Joining, by = "student_ID"

Models

E-V predicting curves

Here are some models, first for antecedents of different intercepts and slopes.

## 
## Call:
## lm(formula = intercept ~ task_value * perceived_competence, data = dfm_b)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -23.736 -11.718   0.088   8.282  74.968 
## 
## Coefficients:
##                                 Estimate Std. Error t value Pr(>|t|)
## (Intercept)                        7.743     42.850   0.181    0.857
## task_value                         7.768     10.659   0.729    0.467
## perceived_competence               4.103     10.748   0.382    0.703
## task_value:perceived_competence   -1.334      2.579  -0.517    0.605
## 
## Residual standard error: 15.12 on 248 degrees of freedom
##   (20 observations deleted due to missingness)
## Multiple R-squared:  0.005945,   Adjusted R-squared:  -0.00608 
## F-statistic: 0.4944 on 3 and 248 DF,  p-value: 0.6865
## 
## Call:
## lm(formula = linear_slope ~ task_value * perceived_competence, 
##     data = dfm_b)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -6.7341 -0.7320  0.0151  1.0462  2.1072 
## 
## Coefficients:
##                                 Estimate Std. Error t value Pr(>|t|)
## (Intercept)                       0.1867     3.8375   0.049    0.961
## task_value                       -0.6895     0.9546  -0.722    0.471
## perceived_competence             -0.3619     0.9626  -0.376    0.707
## task_value:perceived_competence   0.1180     0.2309   0.511    0.610
## 
## Residual standard error: 1.354 on 248 degrees of freedom
##   (20 observations deleted due to missingness)
## Multiple R-squared:  0.0059, Adjusted R-squared:  -0.006125 
## F-statistic: 0.4906 on 3 and 248 DF,  p-value: 0.6891
## 
## Call:
## lm(formula = intercept ~ cost_value * perceived_competence, data = dfm_b)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -25.093 -11.067  -0.411   8.480  73.828 
## 
## Coefficients:
##                                 Estimate Std. Error t value Pr(>|t|)  
## (Intercept)                      -24.114     29.357  -0.821   0.4122  
## cost_value                        17.012      8.479   2.006   0.0459 *
## perceived_competence              13.534      7.005   1.932   0.0545 .
## cost_value:perceived_competence   -3.956      1.978  -2.000   0.0466 *
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 15.04 on 248 degrees of freedom
##   (20 observations deleted due to missingness)
## Multiple R-squared:  0.01606,    Adjusted R-squared:  0.004161 
## F-statistic:  1.35 on 3 and 248 DF,  p-value: 0.2589
## To invalidate the inference, 1.84 % of the estimate would have to be due to bias.
## To invalidate the inference, 5 observations would have to be replaced with cases for which there is no effect.
## 
## Call:
## lm(formula = linear_slope ~ cost_value * perceived_competence, 
##     data = dfm_b)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -6.6274 -0.7628  0.0645  0.9673  2.2309 
## 
## Coefficients:
##                                 Estimate Std. Error t value Pr(>|t|)  
## (Intercept)                       2.9920     2.6296   1.138   0.2563  
## cost_value                       -1.4998     0.7595  -1.975   0.0494 *
## perceived_competence             -1.1998     0.6275  -1.912   0.0570 .
## cost_value:perceived_competence   0.3499     0.1771   1.975   0.0493 *
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 1.347 on 248 degrees of freedom
##   (20 observations deleted due to missingness)
## Multiple R-squared:  0.01561,    Adjusted R-squared:  0.003707 
## F-statistic: 1.311 on 3 and 248 DF,  p-value: 0.2713
## 
## Call:
## lm(formula = intercept ~ utility_value * perceived_competence, 
##     data = dfm_b)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -23.686 -11.581   0.325   8.557  74.870 
## 
## Coefficients:
##                                    Estimate Std. Error t value Pr(>|t|)
## (Intercept)                          31.208     41.564   0.751    0.453
## utility_value                         1.720      9.833   0.175    0.861
## perceived_competence                 -1.864     10.736  -0.174    0.862
## utility_value:perceived_competence    0.153      2.458   0.062    0.950
## 
## Residual standard error: 15.12 on 248 degrees of freedom
##   (20 observations deleted due to missingness)
## Multiple R-squared:  0.005249,   Adjusted R-squared:  -0.006784 
## F-statistic: 0.4362 on 3 and 248 DF,  p-value: 0.7273
## 
## Call:
## lm(formula = linear_slope ~ utility_value * perceived_competence, 
##     data = dfm_b)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -6.7254 -0.7508 -0.0048  1.0095  2.1020 
## 
## Coefficients:
##                                    Estimate Std. Error t value Pr(>|t|)
## (Intercept)                        -1.90310    3.72251  -0.511    0.610
## utility_value                      -0.14975    0.88063  -0.170    0.865
## perceived_competence                0.16737    0.96149   0.174    0.862
## utility_value:perceived_competence -0.01414    0.22016  -0.064    0.949
## 
## Residual standard error: 1.354 on 248 degrees of freedom
##   (20 observations deleted due to missingness)
## Multiple R-squared:  0.00512,    Adjusted R-squared:  -0.006915 
## F-statistic: 0.4254 on 3 and 248 DF,  p-value: 0.7349

E-V predicting final grades

Here are models with the antecedents predicting final grade

m3 <- lm(final_grade ~ task_value * perceived_competence, data = dfm_b)
summary(m3)
## 
## Call:
## lm(formula = final_grade ~ task_value * perceived_competence, 
##     data = dfm_b)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -41.019  -7.050   1.993   7.841  20.421 
## 
## Coefficients:
##                                 Estimate Std. Error t value Pr(>|t|)  
## (Intercept)                       11.364     29.427   0.386   0.6997  
## task_value                        14.918      7.320   2.038   0.0426 *
## perceived_competence              14.440      7.381   1.956   0.0515 .
## task_value:perceived_competence   -2.836      1.771  -1.601   0.1106  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 10.38 on 248 degrees of freedom
##   (20 observations deleted due to missingness)
## Multiple R-squared:  0.09329,    Adjusted R-squared:  0.08232 
## F-statistic: 8.506 on 3 and 248 DF,  p-value: 2.125e-05
konfound::konfound(m3, task_value)
## To invalidate the inference, 3.36 % of the estimate would have to be due to bias.
## To invalidate the inference, 8 observations would have to be replaced with cases for which there is no effect.
m4 <- lm(final_grade ~ mastery_approach + performance_approach + performance_avoid, data = dfm_b)
summary(m4)
## 
## Call:
## lm(formula = final_grade ~ mastery_approach + performance_approach + 
##     performance_avoid, data = dfm_b)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -40.111  -7.308   1.791   8.539  20.870 
## 
## Coefficients:
##                      Estimate Std. Error t value Pr(>|t|)    
## (Intercept)           68.0625     5.6055  12.142   <2e-16 ***
## mastery_approach       0.5390     1.8857   0.286   0.7752    
## performance_approach   0.2353     1.3403   0.176   0.8608    
## performance_avoid      3.4975     1.7647   1.982   0.0486 *  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 10.67 on 248 degrees of freedom
##   (20 observations deleted due to missingness)
## Multiple R-squared:  0.04301,    Adjusted R-squared:  0.03143 
## F-statistic: 3.715 on 3 and 248 DF,  p-value: 0.01214
konfound::konfound(m4, performance_avoid)
## To invalidate the inference, 0.63 % of the estimate would have to be due to bias.
## To invalidate the inference, 2 observations would have to be replaced with cases for which there is no effect.
m3 <- lm(final_grade ~ cost_value * perceived_competence, data = dfm_b)
summary(m3)
## 
## Call:
## lm(formula = final_grade ~ cost_value * perceived_competence, 
##     data = dfm_b)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -41.581  -6.738   1.752   7.463  20.691 
## 
## Coefficients:
##                                 Estimate Std. Error t value Pr(>|t|)  
## (Intercept)                       36.204     20.359   1.778   0.0766 .
## cost_value                         8.766      5.881   1.491   0.1373  
## perceived_competence               9.632      4.858   1.983   0.0485 *
## cost_value:perceived_competence   -1.614      1.371  -1.177   0.2404  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 10.43 on 248 degrees of freedom
##   (20 observations deleted due to missingness)
## Multiple R-squared:  0.08473,    Adjusted R-squared:  0.07366 
## F-statistic: 7.653 on 3 and 248 DF,  p-value: 6.522e-05

Also looked at outcomes. Adjusted the linear term to be associated with changes per day, though I’m still having a hard time interpreting these coefficients. That said, it doesn’t look like the intercept is (linearly) associated with lower final grades, which is somewhat surprising, but maybe not entirely because quartile 3 demonstrated higher final grades.

## 
## Call:
## lm(formula = final_grade ~ intercept + I(linear_slope * 4) + 
##     task_value + perceived_competence, data = dfm_b)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -33.175  -5.023   0.790   6.442  21.467 
## 
## Coefficients:
##                      Estimate Std. Error t value Pr(>|t|)    
## (Intercept)           -84.415     20.168  -4.186 3.96e-05 ***
## intercept              13.703      1.937   7.074 1.54e-11 ***
## I(linear_slope * 4)    37.701      5.408   6.972 2.84e-11 ***
## task_value              2.907      1.306   2.225   0.0270 *  
## perceived_competence    3.169      1.341   2.363   0.0189 *  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 9.146 on 247 degrees of freedom
##   (20 observations deleted due to missingness)
## Multiple R-squared:  0.2991, Adjusted R-squared:  0.2878 
## F-statistic: 26.36 on 4 and 247 DF,  p-value: < 2.2e-16
## 
## Call:
## lm(formula = final_grade ~ intercept, data = dfm_b)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -36.255  -6.785   1.107   8.263  20.523 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 76.98386    1.57793  48.788  < 2e-16 ***
## intercept    0.20928    0.04304   4.862 2.04e-06 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 10.35 on 254 degrees of freedom
##   (16 observations deleted due to missingness)
## Multiple R-squared:  0.08514,    Adjusted R-squared:  0.08154 
## F-statistic: 23.64 on 1 and 254 DF,  p-value: 2.039e-06
## 
## Call:
## lm(formula = final_grade ~ linear_slope, data = dfm_b)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -36.418  -6.895   1.096   8.242  20.612 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   79.2213     1.1978  66.140  < 2e-16 ***
## linear_slope  -2.2771     0.4818  -4.726 3.79e-06 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 10.37 on 254 degrees of freedom
##   (16 observations deleted due to missingness)
## Multiple R-squared:  0.08083,    Adjusted R-squared:  0.07721 
## F-statistic: 22.34 on 1 and 254 DF,  p-value: 3.794e-06
## 
## Call:
## lm(formula = final_grade ~ intercept + I(linear_slope * 4) + 
##     cost_value + perceived_competence, data = dfm_b)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -33.714  -5.088   0.620   6.588  20.873 
## 
## Coefficients:
##                      Estimate Std. Error t value Pr(>|t|)    
## (Intercept)          -78.8755    20.2782  -3.890 0.000129 ***
## intercept             13.3776     1.9701   6.790 8.28e-11 ***
## I(linear_slope * 4)   36.7772     5.4995   6.687 1.51e-10 ***
## cost_value             1.0760     0.8437   1.275 0.203384    
## perceived_competence   4.4864     1.1391   3.938 0.000107 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 9.207 on 247 degrees of freedom
##   (20 observations deleted due to missingness)
## Multiple R-squared:  0.2898, Adjusted R-squared:  0.2783 
## F-statistic: 25.19 on 4 and 247 DF,  p-value: < 2.2e-16
dfm_b %>% ggplot(aes(y = final_grade, x = intercept)) + geom_point() + geom_smooth(method = "lm")
## Warning: Removed 16 rows containing non-finite values (stat_smooth).
## Warning: Removed 16 rows containing missing values (geom_point).

dfm_b %>% ggplot(aes(y = final_grade, x = linear_slope)) + geom_point() + geom_smooth(method = 'lm')
## Warning: Removed 16 rows containing non-finite values (stat_smooth).

## Warning: Removed 16 rows containing missing values (geom_point).

dfm_b %>% ggplot(aes(y = final_grade, x = intercept)) + geom_point() + geom_smooth()
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'
## Warning: Removed 16 rows containing non-finite values (stat_smooth).

## Warning: Removed 16 rows containing missing values (geom_point).

dfm_b %>% ggplot(aes(y = final_grade, x = linear_slope)) + geom_point() + geom_smooth()
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'
## Warning: Removed 16 rows containing non-finite values (stat_smooth).

## Warning: Removed 16 rows containing missing values (geom_point).