library(psych) # for the describe() command
library(broom) # for the augment() command
## Warning: package 'broom' was built under R version 4.3.3
library(ggplot2) # to visualize our results
## Warning: package 'ggplot2' was built under R version 4.3.3
##
## Attaching package: 'ggplot2'
## The following objects are masked from 'package:psych':
##
## %+%, alpha
# import the dataset you cleaned previously
# this will be the dataset you'll use throughout the rest of the semester
# use Covid Data data
d <- read.csv(file="Data/Covid_Data_Final.csv", header=T)
I hypothesize that anxiety levels (measured by the GAD) will significantly predict covid related anxiety (measured by the PAS), and that the relationship will be positive. This means that more general anxiety leads to more covid related anxiety.
# you only need to check the variables you're using in the current analysis
# although you checked them previously, it's always a good idea to look them over again and be sure that everything is correct
str(d)
## 'data.frame': 1113 obs. of 6 variables:
## $ health : chr "something else or not applicable" "something else or not applicable" "something else or not applicable" "two conditions" ...
## $ mhealth : chr "none or NA" "anxiety disorder" "none or NA" "none or NA" ...
## $ gad : num 1.86 3.86 1.14 2 1.43 ...
## $ phq : num 1.33 3.33 1 2.33 1.11 ...
## $ iou : num 3.19 4 1.59 3.37 1.7 ...
## $ pas_covid: num 3.22 4.56 3.33 4.22 3.22 ...
# you can use the describe() command on an entire dataframe (d) or just on a single variable
describe(d)
## vars n mean sd median trimmed mad min max range skew kurtosis
## health* 1 1113 8.61 1.37 9.00 8.92 0.00 1 11 10 -2.32 6.08
## mhealth* 2 1113 4.64 1.41 5.00 4.88 0.00 1 8 7 -1.42 2.59
## gad 3 1113 2.04 0.92 1.71 1.95 0.85 1 4 3 0.69 -0.72
## phq 4 1113 2.07 0.87 1.89 1.99 0.99 1 4 3 0.64 -0.68
## iou 5 1113 2.56 0.91 2.41 2.50 0.99 1 5 4 0.51 -0.56
## pas_covid 6 1113 3.23 0.69 3.22 3.24 0.66 1 5 4 -0.18 -0.03
## se
## health* 0.04
## mhealth* 0.04
## gad 0.03
## phq 0.03
## iou 0.03
## pas_covid 0.02
# also use histograms to examine your continuous variables
hist(d$gad)
hist(d$pas_covid)
# last, use scatterplots to examine your continuous variables together
plot(d$gad, d$pas_covid)
# to calculate standardized coefficients, we have to standardize our IV
d$gad_std <- scale(d$gad, center=T, scale=T)
hist(d$gad_std)
# use the lm() command to run the regression
# dependent/outcome variable on the left, idependent/predictor variable on the right
reg_model <- lm(pas_covid ~ gad_std, data = d)
model.diag.metrics <- augment(reg_model)
ggplot(model.diag.metrics, aes(x = gad_std, y = pas_covid)) +
geom_point() +
stat_smooth(method = lm, se = FALSE) +
geom_segment(aes(xend = gad_std, yend = .fitted), color = "red", size = 0.3)
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## `geom_smooth()` using formula = 'y ~ x'
This plot (below) shows the residuals for each case and the fitted line. The red line is the average residual for the specified point of the dependent variable. If the assumption of linearity is met, the red line should be horizontal. This indicates that the residuals average to around zero. You can see that for this lab, the plot shows some non-linearity because there are more datapoints below the regression line than here are above it. Thus, there are some negative residuals that don’t have positive residuals to cancel them out. However, a bit of deviation is okay – just like with skewness and kurtosis, there’s a range that we can work in before non-normality or non-linearity becomes a critical issue.
For some examples of good Residuals vs Fitted plot and ones that show serious errors, check out this page. I’ve included the images in our video and talk about them more in-depth there. But to summarize quickly, you can see the first case has a plot in which the red line sticks pretty closely to the zero line, while the other cases show some serious deviation. Ours is much closer to the ‘good’ plot than it is to the ‘serious issues’ plots. So we’ll consider our data okay and proceed with our analysis. Obviously, this is quite subjective. I’ll talk a bit about why this is in the video, but the key takeaway is that these evaluations are closely tied to the context of our sample, our data, and what we’re studying. It’s almost always a judgement call.
You’ll notice in the bottom right corner, there are some points with numbers included: these are cases or participants (indicated by row number) who have the most influence on the regression line (and so they might outliers).We’ll talk more about outliers in the next section.
To summarize: our plot suggests there is some minor non-linearity. For your homework, you’ll simply need to generate this plot and talk about how your plot compares to the good and problematic plots linked to above. Is it closer to the ‘good’ plots or one of the ‘bad’ plots? This is going to be a judgement call, and that’s okay! In practice, you’ll always be making these judgement calls as part of a team, so this assignment is just about getting experience with it, not making the perfect call.
plot(reg_model, 1)
The plots below both address leverage, or how much each data point is able to influence the regression line. Outliers are points that have undue influence on the regression line, the way that Bill Gates entering the room has an undue influence on the mean income.
The first plot, Cook’s distance, is a visualization of a score called (you guessed it) Cook’s distance, calculated for each case (aka row or participant) in the dataframe. Cook’s distance tells us how much the regression would change if the point was removed. Ideally, we want all points to have the same influence on the regression line, although we accept that there will be some variability. The cutoff for a high Cook’s distance score is .5 (not .05, which is our cutoff for statistical significance). For our data, some points do exert more influence than others but they’re generally equal, and none of them are close to the cutoff.
The second plot also includes the residuals in the examination of leverage. The standardized residuals are on the y-axis and leverage is on the x-axis; this shows us which points have high residuals (are far from the regression line) and high leverage. Point that have large residuals and high leverage are especially worrisome, because they are far from the regression line but are also exerting a large influence on it. The red line indicates the average residual across points with the same amount of leverage. As usual, we want this line to stay as close to the mean line (or the zero line) as possible.
Because the leverage in our plot is low, part of it actually cut off! If you check the first set of plots on this page (note that Residuals vs Leverage is the fourth in the grid) you can see there are curved red lines in the corners of the Residuals vs Leverage plots. This is the .5 cutoff for Cook’s distance, and so any points appearing past these lines is a serious outlier that needs to be removed. On this page you can also see Residuals vs Leverage plots with severe deviations from the mean line, which makes our deviations appear much less serious.
Our data doesn’t have any severe outliers. For your homework, you’ll simply need to generate these plots, assess Cook’s distance in your dataset, and then identify any potential cases that are prominent outliers. Since we have some cutoffs, that makes this process is a bit less subjective than some of the other assessments we’ve done here, which is a nice change!
# Cook's distance
plot(reg_model, 4)
# Residuals vs Leverage
plot(reg_model, 5)
Before interpreting our results, I assessed my variables to see if they met the assumptions for a simple linear regression. Looking at my Residuals vs Fitted Plot showed that there is little to no non-linearity as it followed the dotted line almost perfectly. I also checked Cook’s distance and the Residuals vs Leverage plot to search for outliers. While we had three data points noted, they actually pulled the Leverage line down closer to the dashed line, showing that they are not skewing our data away from linearity. It couldn’t be much better, honestly! In my spare time I will likely compare some other data from this set to get some extra experience.
summary(reg_model)
##
## Call:
## lm(formula = pas_covid ~ gad_std, data = d)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.5598 -0.3783 0.0282 0.4239 1.8195
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 3.23061 0.01897 170.30 <2e-16 ***
## gad_std 0.27803 0.01898 14.65 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.6329 on 1111 degrees of freedom
## Multiple R-squared: 0.1619, Adjusted R-squared: 0.1611
## F-statistic: 214.6 on 1 and 1111 DF, p-value: < 2.2e-16
# note for section below: to type lowercase Beta below (ß) you need to hold down Alt key and type 225 on numeric keypad. If that doesn't work you should be able to copy/paste it from somewhere else
To test my hypothesis that generalized anxiety (measured by the GAD) significantly and positively predicts pandemic related anxiety (measured by the PAS), I used a simple linear regression to model the relationship between the two variables. I confiemd that my data more than met the assumptions of a linear regression by looking at the Residuals vs Fitted plot and checked for outliers using both Cook’s distance and the Residuals vs Leverage plot.
As I predicted, I did find that generalized anxiety significantly and positively predicted pandemic related anxiety. R2 = .16, F(1, 1111) = 214.6, and p < .001. We can tell it is positive, ß = .27, t(1111) = 14.65, p < .001 (refer to Figure 1). According to Cohen (1988), this constitutes a medium to small effect size.
References
Cohen J. (1988). Statistical Power Analysis for the Behavioral Sciences. New York, NY: Routledge Academic.