Select variables of interest

V241221 (party id); V241177 (ideology); V241551 (gender); V241501x (race); V242337 (social class); V241465x (education); V241566x (household income); V241458x (age); V242305 (Because of the rich and powerful, it becomes difficult for the rest of us to get ahead); V242350 (minimum wage increase); V242316b (tax on millionaires); V242253x (government should reduce income inequality).

df_anes <- df_anes_raw %>% 
  rename(party_id = V241221,
         ideo = V241177,
         gender = V241551,
         race = V241501x,
         class = V242337,
         class_mid = V242338,
         edu = V241465x,
         income = V241566x,
         age = V241458x,
         class_zs = V242305,
         minwage = V242350,
         taxrich = V242316b,
         reduceineq = V242253x) %>% 
  select(party_id,
         ideo,
         gender,
         race,
         class,
         class_mid,
         edu,
         income,
         age,
         class_zs,
         minwage,
         reduceineq)

clean data

df_anes <- df_anes %>% 
  mutate(party_id = case_when(party_id == 1 ~ "dem",
                              party_id == 2 ~ "rep",
                              party_id == 3 ~ "ind",
                              party_id == 5 ~ "other",
                              .default = NA),
         ideo = case_when(ideo < 0 ~ NA,
                          ideo == 99 ~ NA,
                          .default = as.numeric(ideo)),
         gender = case_when(gender == 1 ~ "man",
                            gender == 2 ~ "woman",
                            gender == 3 ~ "nonbinary",
                            gender == 4 ~ "other",
                            .default = NA),
         race = case_when(race == 1 ~ "white,non-hisp",
                          race == 2 ~ "black,non-hisp",
                          race == 3 ~ "hisp",
                          race == 4 ~ "asian,non-hisp",
                          race == 5 ~ "native,non-hisp",
                          race == 6 ~ "multiracial,non-hisp",
                          .default = NA),
         class = case_when(class == 1 ~ "lower",
                           class == 2 ~ "working",
                           class == 3 ~ "middle",
                           class == 4 ~ "upper",
                           .default = NA),
         class = case_when(class == "middle" & class_mid == 1 ~ "middle-lower",
                           class == "middle" & class_mid == 2 ~ "middle-mid",
                           class == "middle" & class_mid == 3 ~ "middle-upper",
                           .default = as.character(class)),
         edu = case_when(edu < 0 ~ NA,
                         .default = as.numeric(edu)),
         income = case_when(income < 0 ~ NA,
                            .default = as.numeric(income)),
         age = case_when(age < 0 ~ NA,
                         .default = as.numeric(age)),
         class_zs = case_when(class_zs < 0 ~ NA,
                              .default = as.numeric(class_zs)),
         minwage = case_when(minwage < 0 ~ NA,
                             .default = as.numeric(minwage)),
         reduceineq = case_when(reduceineq < 0 ~ NA,
                                .default = as.numeric(reduceineq))) %>% 
  mutate(minwage_R = 5 - minwage,
         reduceineq_R = 8 - reduceineq,
         class_num = as.numeric(factor(class,levels = c("lower",
                                                           "working",
                                                        "middle-lower",
                                                        "middle-mid",
                                                        "middle-upper",
                                                           "upper"))))

Lemme see if i can get an objective identity of working class (I’ll just do with vs. without a bachelor’s degree) and a subjective identity of lower and working class (I’ll do lower and working as 1 vs. anything else as 0)

df_anes <- df_anes %>% 
  mutate(wrkclass_obj = ifelse(edu > 3,0,1),
         class_subjbin = ifelse(class == "lower" | class == "working",1,0))

Descriptives

Alright, let’s take a look at our sample.

Race

df_anes %>% 
  group_by(race) %>% 
  summarise(N = n()) %>% 
  ungroup() %>% 
  mutate(Perc = round(100*(N/sum(N)),2)) %>% 
  ungroup() %>% 
  arrange(desc(N)) %>% 
  kbl() %>% 
  kable_styling(bootstrap_options = "hover",
                full_width = F,
                position = "left")
race N Perc
white,non-hisp 3946 71.47
hisp 582 10.54
black,non-hisp 508 9.20
asian,non-hisp 197 3.57
multiracial,non-hisp 188 3.41
NA 67 1.21
native,non-hisp 33 0.60

Gender

df_anes %>% 
  group_by(gender) %>% 
  summarise(N = n()) %>% 
  ungroup() %>% 
  mutate(Perc = round(100*(N/sum(N)),2)) %>% 
  ungroup() %>% 
  arrange(desc(N)) %>% 
  kbl() %>% 
  kable_styling(bootstrap_options = "hover",
                full_width = F,
                position = "left")
gender N Perc
woman 2773 50.23
man 2397 43.42
NA 287 5.20
nonbinary 46 0.83
other 18 0.33

Education

  1. Less than high-school
  2. High school
  3. Some post high-school
  4. Bachelor’s degree
  5. Graduate degree
df_anes %>% 
  group_by(edu) %>% 
  summarise(N = n()) %>% 
  ungroup() %>% 
  mutate(Perc = round(100*(N/sum(N)),2)) %>% 
  ungroup() %>% 
  arrange(edu) %>% 
  kbl() %>% 
  kable_styling(bootstrap_options = "hover",
                full_width = F,
                position = "left")
edu N Perc
1 282 5.11
2 971 17.59
3 1726 31.26
4 1374 24.89
5 1081 19.58
NA 87 1.58

Income

1 = Under 5000 to 28 = Over 250,000

df_anes %>% 
  ggplot(aes(x = income)) +
  geom_histogram(fill = "lightblue",
                 color = NA,
                 binwidth = 1) +
  scale_x_continuous(breaks = seq(1,28,3),
                     limits = c(0,29)) +
  geom_vline(xintercept = median(df_anes$income,na.rm = T),
             color = "grey15",
             size = 1,
             linetype = "dashed") +
  theme(panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_blank(),
        axis.ticks = element_blank(),
        axis.line = element_line(color = "grey66"),
        axis.text.y = element_text(color = "black"),
        axis.text.x = element_text(color = "black",
                                   face = "bold"),
        axis.title.x = element_text(color = "black",
                                   face = "bold"))

Class

df_anes %>% 
  group_by(class) %>% 
  summarise(N = n()) %>% 
  ungroup() %>% 
  mutate(Perc = round(100*(N/sum(N)),2)) %>% 
  ungroup() %>% 
  kbl() %>% 
  kable_styling(bootstrap_options = "hover",
                full_width = F,
                position = "left")
class N Perc
lower 418 7.57
middle 96 1.74
middle-lower 540 9.78
middle-mid 1233 22.33
middle-upper 651 11.79
upper 263 4.76
working 1707 30.92
NA 613 11.10

Class and education

I just want to square them to see how many people identify as working class even when they have a bachelor’s degree

df_anes %>% 
  group_by(edu,class) %>% 
  summarise(N = n()) %>% 
  ungroup() %>% 
  kbl() %>% 
  kable_styling(bootstrap_options = "hover",
                full_width = F,
                position = "left")
## `summarise()` has grouped output by 'edu'. You can override using the `.groups`
## argument.
edu class N
1 lower 45
1 middle 1
1 middle-lower 22
1 middle-mid 40
1 middle-upper 7
1 upper 6
1 working 104
1 NA 57
2 lower 153
2 middle 19
2 middle-lower 72
2 middle-mid 139
2 middle-upper 40
2 upper 18
2 working 398
2 NA 132
3 lower 155
3 middle 24
3 middle-lower 158
3 middle-mid 352
3 middle-upper 112
3 upper 26
3 working 695
3 NA 204
4 lower 43
4 middle 27
4 middle-lower 171
4 middle-mid 364
4 middle-upper 228
4 upper 81
4 working 339
4 NA 121
5 lower 13
5 middle 21
5 middle-lower 113
5 middle-mid 316
5 middle-upper 259
5 upper 131
5 working 148
5 NA 80
NA lower 9
NA middle 4
NA middle-lower 4
NA middle-mid 22
NA middle-upper 5
NA upper 1
NA working 23
NA NA 19

Subjective and objective class

I binarized education and subjective class, to see in an interaction later on.
wrkclass_obj: 0 = anyone with a bachelor’s degree and higher; 1 = anyone with less than a bachelor’s degree. class_subjbin: = 0 = anyone who identified as lower-middle, middle, upper-middle, or upper; 1 = anyone who identified as lower or working.

df_anes %>% 
  group_by(wrkclass_obj,
           class_subjbin) %>% 
  summarise(N = n()) %>% 
  ungroup() %>% 
  kbl() %>% 
  kable_styling(bootstrap_options = "hover",
                full_width = F,
                position = "left")
## `summarise()` has grouped output by 'wrkclass_obj'. You can override using the
## `.groups` argument.
wrkclass_obj class_subjbin N
0 0 1711
0 1 543
0 NA 201
1 0 1036
1 1 1550
1 NA 393
NA 0 36
NA 1 32
NA NA 19

Age

Note that they just assigned 80 to anyone over 80, so it looks skewed.

df_anes %>% 
  ggplot(aes(x = age)) +
  geom_histogram(fill = "lightblue",
                 color = NA,
                 binwidth = 1) +
  # scale_x_continuous(breaks = seq(1,28,3),
  #                    limits = c(0,29)) +
  geom_vline(xintercept = mean(df_anes$age,na.rm = T),
             color = "grey15",
             size = 1,
             linetype = "dashed") +
  theme(panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_blank(),
        axis.ticks = element_blank(),
        axis.line = element_line(color = "grey66"),
        axis.text.y = element_text(color = "black"),
        axis.text.x = element_text(color = "black",
                                   face = "bold"),
        axis.title.x = element_text(color = "black",
                                   face = "bold"))

Party ID

df_anes %>% 
  group_by(party_id) %>% 
  summarise(N = n()) %>% 
  ungroup() %>% 
  mutate(Perc = round(100*(N/sum(N)),2)) %>% 
  ungroup() %>% 
  arrange(desc(N)) %>% 
  kbl() %>% 
  kable_styling(bootstrap_options = "hover",
                full_width = F,
                position = "left")
party_id N Perc
dem 1865 33.78
rep 1652 29.92
ind 1553 28.13
NA 298 5.40
other 153 2.77

Political ideology

1 = Extremely Liberal to 7 = Extremely Conservative

df_anes %>% 
  ggplot(aes(x = ideo)) +
  geom_histogram(fill = "lightblue",
                 color = NA,
                 binwidth = 1) +
  scale_x_continuous(breaks = seq(1,7,1),
                      limits = c(0,8)) +
  geom_vline(xintercept = mean(df_anes$ideo,na.rm = T),
             color = "grey15",
             size = 1,
             linetype = "dashed") +
  theme(panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_blank(),
        axis.ticks = element_blank(),
        axis.line = element_line(color = "grey66"),
        axis.text.y = element_text(color = "black"),
        axis.text.x = element_text(color = "black",
                                   face = "bold"),
        axis.title.x = element_text(color = "black",
                                   face = "bold"))

Class Zero-Sum

How well does the following statement describe your view? (1 = Not at all well to 5 = Extremely well)

Because of the rich and powerful, it becomes difficult for the rest of us to get ahead.

df_anes %>% 
  ggplot(aes(x = class_zs)) +
  geom_histogram(fill = "lightblue",
                 color = NA,
                 binwidth = 1) +
  scale_x_continuous(breaks = seq(1,5,1),
                    limits = c(0,6)) +
  geom_vline(xintercept = mean(df_anes$class_zs,na.rm = T),
             color = "grey15",
             size = 1,
             linetype = "dashed") +
  theme(panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_blank(),
        axis.ticks = element_blank(),
        axis.line = element_line(color = "grey66"),
        axis.text.y = element_text(color = "black"),
        axis.text.x = element_text(color = "black",
                                   face = "bold"),
        axis.title.x = element_text(color = "black",
                                   face = "bold"))

Minimum wage increase

Should the federal minimum wage be [raised (4), kept the same (3),lowered but not eliminated (2), or eliminated altogether (1)]?

df_anes %>% 
  ggplot(aes(x = minwage_R)) +
  geom_histogram(fill = "lightblue",
                 color = NA,
                 binwidth = 1) +
  scale_x_continuous(breaks = seq(1,4,1),
                    limits = c(0,5)) +
  geom_vline(xintercept = mean(df_anes$minwage_R,na.rm = T),
             color = "grey15",
             size = 1,
             linetype = "dashed") +
  theme(panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_blank(),
        axis.ticks = element_blank(),
        axis.line = element_line(color = "grey66"),
        axis.text.y = element_text(color = "black"),
        axis.text.x = element_text(color = "black",
                                   face = "bold"),
        axis.title.x = element_text(color = "black",
                                   face = "bold"))

Reduce inequality

Do you favor or oppose, or neither favor nor oppose the government trying to reduce the difference in incomes between the richest and poorest households? (1 = Oppose a great deal to 7 = Favor a great deal)

df_anes %>% 
  ggplot(aes(x = reduceineq_R)) +
  geom_histogram(fill = "lightblue",
                 color = NA,
                 binwidth = 1) +
  scale_x_continuous(breaks = seq(1,7,1),
                    limits = c(0,8)) +
  geom_vline(xintercept = mean(df_anes$reduceineq_R,na.rm = T),
             color = "grey15",
             size = 1,
             linetype = "dashed") +
  theme(panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_blank(),
        axis.ticks = element_blank(),
        axis.line = element_line(color = "grey66"),
        axis.text.y = element_text(color = "black"),
        axis.text.x = element_text(color = "black",
                                   face = "bold"),
        axis.title.x = element_text(color = "black",
                                   face = "bold"))

Analysis

Correlation matrix

df_anes %>% 
  select(class_zs,minwage_R,reduceineq,ideo,income,edu,age,class_num) %>%
  corPlot(upper = TRUE,stars = TRUE,xsrt = 270)

The “reducing inequality” item looks very weird. Feels like they made a coding error, or the codebook is wrong. I think it’s the opposite of what they’re saying. Hmm. The rest makes sense.

Linear models

Linear model 1A

Outcome: Minimum wage support; predictor: class zero-sum.

m1 <- lm(minwage_R ~ class_zs,data = df_anes)

apa_lm <- apa_print(m1)

kbl(apa_lm$table) %>% 
  kable_styling(bootstrap_options = "hover",
                full_width = F,
                position = "left")
term estimate conf.int statistic df p.value
Intercept 2.81 [2.74, 2.88] 82.54 4854 < .001
Class zs 0.19 [0.17, 0.21] 19.15 4854 < .001

Linear model 1B

Outcome: Minimum wage support;
Predictor: class zero-sum;
Controls: Party ID and political ideology

m1 <- lm(minwage_R ~ class_zs + party_id + ideo,data = df_anes)

apa_lm <- apa_print(m1)
kbl(apa_lm$table) %>% 
  kable_styling(bootstrap_options = "hover",
                full_width = F,
                position = "left")
term estimate conf.int statistic df p.value
Intercept 3.79 [3.68, 3.90] 66.20 4045 < .001
Class zs 0.10 [0.08, 0.12] 8.91 4045 < .001
Party idind -0.14 [-0.20, -0.07] -4.21 4045 < .001
Party idother -0.47 [-0.63, -0.31] -5.67 4045 < .001
Party idrep -0.29 [-0.37, -0.21] -7.04 4045 < .001
Ideo -0.13 [-0.15, -0.11] -13.26 4045 < .001

Linear model 1C

Outcome: Minimum wage support;
Predictor: class zero-sum;
Controls: Party ID, political ideology, race, gender, income, education, and age

m1 <- lm(minwage_R ~ class_zs + party_id + ideo + race + gender + income + edu + age,data = df_anes)

apa_lm <- apa_print(m1)
kbl(apa_lm$table) %>% 
  kable_styling(bootstrap_options = "hover",
                full_width = F,
                position = "left")
term estimate conf.int statistic df p.value
Intercept 3.76 [3.53, 3.99] 32.00 3676 < .001
Class zs 0.10 [0.08, 0.12] 8.47 3676 < .001
Party idind -0.10 [-0.17, -0.03] -2.90 3676 .004
Party idother -0.45 [-0.62, -0.27] -5.09 3676 < .001
Party idrep -0.27 [-0.36, -0.19] -6.34 3676 < .001
Ideo -0.13 [-0.16, -0.11] -12.51 3676 < .001
Raceblack,non-hisp 0.07 [-0.10, 0.23] 0.81 3676 .415
Racehisp 0.10 [-0.05, 0.26] 1.30 3676 .192
Racemultiracial,non-hisp 0.07 [-0.12, 0.26] 0.74 3676 .459
Racenative,non-hisp 0.12 [-0.28, 0.51] 0.58 3676 .562
Racewhite,non-hisp 0.00 [-0.14, 0.13] -0.03 3676 .973
Gendernonbinary 0.13 [-0.13, 0.38] 0.97 3676 .331
Genderother 0.05 [-0.48, 0.58] 0.19 3676 .849
Genderwoman 0.14 [0.09, 0.19] 5.41 3676 < .001
Income 0.00 [-0.01, 0.00] -1.21 3676 .228
Edu -0.02 [-0.05, 0.00] -1.87 3676 .061
Age 0.00 [0.00, 0.00] 1.39 3676 .165

Linear model 1D

Outcome: Minimum wage support;
Predictor: class zero-sum;
Controls: Party ID, political ideology, race, gender, income, education, age, and class

m1 <- lm(minwage_R ~ class_zs + party_id + ideo + race + gender + income + edu + age + class,data = df_anes)

apa_lm <- apa_print(m1)
kbl(apa_lm$table) %>% 
  kable_styling(bootstrap_options = "hover",
                full_width = F,
                position = "left")
term estimate conf.int statistic df p.value
Intercept 3.76 [3.52, 4.00] 30.28 3668 < .001
Class zs 0.10 [0.08, 0.12] 8.30 3668 < .001
Party idind -0.10 [-0.17, -0.04] -2.97 3668 .003
Party idother -0.45 [-0.62, -0.27] -5.10 3668 < .001
Party idrep -0.27 [-0.36, -0.19] -6.35 3668 < .001
Ideo -0.13 [-0.16, -0.11] -12.43 3668 < .001
Raceblack,non-hisp 0.07 [-0.10, 0.23] 0.80 3668 .423
Racehisp 0.11 [-0.05, 0.26] 1.32 3668 .186
Racemultiracial,non-hisp 0.07 [-0.12, 0.26] 0.72 3668 .471
Racenative,non-hisp 0.11 [-0.29, 0.50] 0.53 3668 .596
Racewhite,non-hisp 0.00 [-0.14, 0.14] 0.01 3668 .989
Gendernonbinary 0.12 [-0.13, 0.37] 0.93 3668 .354
Genderother 0.04 [-0.48, 0.57] 0.16 3668 .873
Genderwoman 0.14 [0.09, 0.19] 5.38 3668 < .001
Income 0.00 [0.00, 0.00] -0.63 3668 .530
Edu -0.02 [-0.05, 0.01] -1.40 3668 .162
Age 0.00 [0.00, 0.00] 1.69 3668 .090
Classmiddle-lower -0.07 [-0.19, 0.06] -1.03 3668 .304
Classmiddle-mid -0.08 [-0.20, 0.04] -1.36 3668 .174
Classmiddle-upper -0.08 [-0.21, 0.05] -1.26 3668 .208
Classupper 0.00 [-0.15, 0.15] 0.00 3668 .998
Classworking -0.02 [-0.13, 0.08] -0.44 3668 .657

Linear model 2A

Let’s just see if class is predictive of minimum wage support at all. Here, we’ll treat class a numeric variable (1 = lower; 2 = working; 3 = middle; 4 = upper).

Outcome: Minimum wage support;
Predictor: class

m1 <- lm(minwage_R ~ class_num,data = df_anes)

apa_lm <- apa_print(m1)
kbl(apa_lm$table) %>% 
  kable_styling(bootstrap_options = "hover",
                full_width = F,
                position = "left")
term estimate conf.int statistic df p.value
Intercept 3.53 [3.47, 3.59] 116.03 4779 < .001
Class num -0.03 [-0.05, -0.02] -3.94 4779 < .001

Linear model 2B

Outcome: Minimum wage support;
Predictor: class;
Controls: Education and income

m1 <- lm(minwage_R ~ class_num + edu + income,data = df_anes)

apa_lm <- apa_print(m1)
kbl(apa_lm$table) %>% 
  kable_styling(bootstrap_options = "hover",
                full_width = F,
                position = "left")
term estimate conf.int statistic df p.value
Intercept 3.49 [3.40, 3.57] 79.43 4376 < .001
Class num -0.04 [-0.06, -0.02] -3.57 4376 < .001
Edu 0.04 [0.02, 0.07] 3.20 4376 .001
Income 0.00 [-0.01, 0.00] -2.46 4376 .014

Linear model 2C

Outcome: Minimum wage support;
Predictor: class;
Controls: Education, income, race, gender, age

m1 <- lm(minwage_R ~ class_num + edu + income + race + gender + age,data = df_anes)

apa_lm <- apa_print(m1)
kbl(apa_lm$table) %>% 
  kable_styling(bootstrap_options = "hover",
                full_width = F,
                position = "left")
term estimate conf.int statistic df p.value
Intercept 3.30 [3.11, 3.48] 34.81 4239 < .001
Class num -0.03 [-0.05, 0.00] -2.41 4239 .016
Edu 0.04 [0.01, 0.06] 2.95 4239 .003
Income 0.00 [0.00, 0.00] -0.57 4239 .566
Raceblack,non-hisp 0.26 [0.10, 0.42] 3.20 4239 .001
Racehisp 0.15 [-0.01, 0.31] 1.86 4239 .063
Racemultiracial,non-hisp 0.07 [-0.12, 0.26] 0.74 4239 .457
Racenative,non-hisp 0.15 [-0.21, 0.50] 0.81 4239 .418
Racewhite,non-hisp -0.02 [-0.16, 0.12] -0.31 4239 .760
Gendernonbinary 0.43 [0.17, 0.69] 3.27 4239 .001
Genderother 0.26 [-0.18, 0.70] 1.16 4239 .247
Genderwoman 0.23 [0.18, 0.28] 8.88 4239 < .001
Age 0.00 [0.00, 0.00] -1.08 4239 .282

Linear model 2D

Outcome: Minimum wage support;
Predictor: class;
Controls: Education, income, race, gender, age, party ID, and political ideology

m1 <- lm(minwage_R ~ class_num + edu + income + race + gender + age + party_id + ideo,data = df_anes)

apa_lm <- apa_print(m1)
kbl(apa_lm$table) %>% 
  kable_styling(bootstrap_options = "hover",
                full_width = F,
                position = "left")
term estimate conf.int statistic df p.value
Intercept 4.27 [4.07, 4.47] 41.38 3678 < .001
Class num -0.02 [-0.04, 0.00] -2.18 3678 .030
Edu -0.02 [-0.05, 0.01] -1.53 3678 .127
Income 0.00 [-0.01, 0.00] -0.94 3678 .348
Raceblack,non-hisp 0.07 [-0.09, 0.24] 0.84 3678 .399
Racehisp 0.10 [-0.05, 0.26] 1.29 3678 .196
Racemultiracial,non-hisp 0.07 [-0.11, 0.26] 0.78 3678 .436
Racenative,non-hisp 0.15 [-0.24, 0.54] 0.76 3678 .445
Racewhite,non-hisp 0.01 [-0.13, 0.14] 0.08 3678 .935
Gendernonbinary 0.12 [-0.14, 0.38] 0.91 3678 .361
Genderother 0.07 [-0.46, 0.61] 0.27 3678 .783
Genderwoman 0.14 [0.09, 0.19] 5.41 3678 < .001
Age 0.00 [0.00, 0.00] 0.29 3678 .775
Party idind -0.12 [-0.19, -0.05] -3.48 3678 < .001
Party idother -0.47 [-0.65, -0.30] -5.37 3678 < .001
Party idrep -0.32 [-0.40, -0.23] -7.34 3678 < .001
Ideo -0.15 [-0.17, -0.13] -14.48 3678 < .001

Linear model 4A

Outcome: Minimum wage support;
Predictor: interaction of subjective and objective class

m1 <- lm(minwage_R ~ wrkclass_obj*class_subjbin,data = df_anes)

apa_lm <- apa_print(m1)
kbl(apa_lm$table) %>% 
  kable_styling(bootstrap_options = "hover",
                full_width = F,
                position = "left")
term estimate conf.int statistic df p.value
Intercept 3.42 [3.38, 3.46] 165.75 4801 < .001
Wrkclass obj -0.11 [-0.18, -0.05] -3.36 4801 < .001
Class subjbin 0.04 [-0.05, 0.12] 0.87 4801 .386
Wrkclass obj \(\times\) Class subjbin 0.15 [0.05, 0.26] 2.81 4801 .005
interact_plot(m1,
              pred = "wrkclass_obj",
              modx = "class_subjbin")

Oh. This is counter-intuitive. Let’s see if I’m reading this interaction right. For those who are not objectively working class (those with a bachelor’s degree or higher), their subjective social class doesn’t really matter: they’ll be relatively supporting of increasing the minimum wage regardless. For those are objective working class (those without a bachelor’s degree or higher), if they identify as higher social class than they actually are, they’ll oppose increasing the minimum wage; those who do identify as working or lower class show the same amount of support for minimum wage increase those who are not objectively part of the working class. The story here may be that believe in mobility, or that they separate themselves from their class, and therefore less likely to support policy that’s in their class interest. Ok - that actually makes more sense now.

Linear model 4B

Let’s add some controls, see if the interaction holds.

Outcome: Minimum wage support;
Predictor: interaction of subjective and objective class;
Controls: race, gender, age political ideology

m1 <- lm(minwage_R ~ wrkclass_obj*class_subjbin + race + gender + age + ideo,data = df_anes)

apa_lm <- apa_print(m1)
kbl(apa_lm$table) %>% 
  kable_styling(bootstrap_options = "hover",
                full_width = F,
                position = "left")
term estimate conf.int statistic df p.value
Intercept 4.07 [3.90, 4.23] 49.12 3815 < .001
Wrkclass obj -0.01 [-0.08, 0.06] -0.21 3815 .835
Class subjbin 0.01 [-0.07, 0.09] 0.33 3815 .741
Raceblack,non-hisp 0.16 [0.00, 0.32] 1.92 3815 .054
Racehisp 0.15 [-0.01, 0.30] 1.84 3815 .066
Racemultiracial,non-hisp 0.11 [-0.08, 0.30] 1.14 3815 .255
Racenative,non-hisp 0.20 [-0.19, 0.59] 1.00 3815 .319
Racewhite,non-hisp 0.01 [-0.13, 0.14] 0.10 3815 .923
Gendernonbinary 0.07 [-0.18, 0.32] 0.53 3815 .597
Genderother 0.22 [-0.29, 0.72] 0.83 3815 .405
Genderwoman 0.15 [0.10, 0.20] 5.81 3815 < .001
Age 0.00 [0.00, 0.00] 1.22 3815 .224
Ideo -0.21 [-0.22, -0.19] -26.66 3815 < .001
Wrkclass obj \(\times\) Class subjbin 0.12 [0.01, 0.23] 2.19 3815 .029
interact_plot(m1,
              pred = "wrkclass_obj",
              modx = "class_subjbin")

YES. If you take away ideology (which explains a ton in support for minimum wage increase, obviously), the interaction looks a lot more like what we’d expect. For those who do not have a bachelor’s degree or higher, their subjective identification doesn’t really matter. But for thow who do, their self-identification matters a lot.

Linear model 4C

Let’s add some controls, see if the interaction holds.

Outcome: Minimum wage support;
Predictor: interaction of subjective and objective class;
Controls: race, gender, age political ideology

m1 <- lm(minwage_R ~ wrkclass_obj*class_subjbin + race + gender + age + ideo,data = df_anes)

apa_lm <- apa_print(m1)
kbl(apa_lm$table) %>% 
  kable_styling(bootstrap_options = "hover",
                full_width = F,
                position = "left")
term estimate conf.int statistic df p.value
Intercept 4.07 [3.90, 4.23] 49.12 3815 < .001
Wrkclass obj -0.01 [-0.08, 0.06] -0.21 3815 .835
Class subjbin 0.01 [-0.07, 0.09] 0.33 3815 .741
Raceblack,non-hisp 0.16 [0.00, 0.32] 1.92 3815 .054
Racehisp 0.15 [-0.01, 0.30] 1.84 3815 .066
Racemultiracial,non-hisp 0.11 [-0.08, 0.30] 1.14 3815 .255
Racenative,non-hisp 0.20 [-0.19, 0.59] 1.00 3815 .319
Racewhite,non-hisp 0.01 [-0.13, 0.14] 0.10 3815 .923
Gendernonbinary 0.07 [-0.18, 0.32] 0.53 3815 .597
Genderother 0.22 [-0.29, 0.72] 0.83 3815 .405
Genderwoman 0.15 [0.10, 0.20] 5.81 3815 < .001
Age 0.00 [0.00, 0.00] 1.22 3815 .224
Ideo -0.21 [-0.22, -0.19] -26.66 3815 < .001
Wrkclass obj \(\times\) Class subjbin 0.12 [0.01, 0.23] 2.19 3815 .029
interact_plot(m1,
              pred = "wrkclass_obj",
              modx = "class_subjbin")

Linear model 5A

Let’s see what happens when we class_zs to the model. I think we’re looking for a three-way interaction (yikes).

Outcome: Minimum wage support;
Predictor: interaction of subjective class, objective class, and class zero-sum beliefs

m1 <- lm(minwage_R ~ wrkclass_obj*class_subjbin*class_zs,data = df_anes)

apa_lm <- apa_print(m1)
kbl(apa_lm$table) %>% 
  kable_styling(bootstrap_options = "hover",
                full_width = F,
                position = "left")
term estimate conf.int statistic df p.value
Intercept 2.73 [2.62, 2.85] 47.36 4778 < .001
Wrkclass obj 0.07 [-0.11, 0.25] 0.78 4778 .437
Class subjbin -0.04 [-0.28, 0.20] -0.31 4778 .757
Class zs 0.22 [0.19, 0.26] 12.66 4778 < .001
Wrkclass obj \(\times\) Class subjbin 0.19 [-0.12, 0.49] 1.21 4778 .227
Wrkclass obj \(\times\) Class zs -0.06 [-0.11, -0.01] -2.15 4778 .032
Class subjbin \(\times\) Class zs 0.00 [-0.07, 0.06] -0.11 4778 .913
Wrkclass obj \(\times\) Class subjbin \(\times\) Class zs 0.00 [-0.08, 0.09] 0.06 4778 .949

Ok, wait, let’s take a step back.

Linear model 5B

Let’s look at each interaction with class_zs separately.

Outcome: Minimum wage support;
Predictor: interaction of subjective class and class zero-sum beliefs

m1 <- lm(minwage_R ~ class_subjbin*class_zs,data = df_anes)

apa_lm <- apa_print(m1)
kbl(apa_lm$table) %>% 
  kable_styling(bootstrap_options = "hover",
                full_width = F,
                position = "left")
term estimate conf.int statistic df p.value
Intercept 2.77 [2.68, 2.86] 62.50 4848 < .001
Class subjbin 0.11 [-0.03, 0.25] 1.60 4848 .110
Class zs 0.20 [0.17, 0.23] 14.71 4848 < .001
Class subjbin \(\times\) Class zs -0.02 [-0.06, 0.02] -1.02 4848 .307

Linear model 5C

Let’s look at each interaction with class_zs separately.

Outcome: Minimum wage support;
Predictor: interaction of objective class and class zero-sum beliefs

m1 <- lm(minwage_R ~ wrkclass_obj*class_zs,data = df_anes)

apa_lm <- apa_print(m1)
kbl(apa_lm$table) %>% 
  kable_styling(bootstrap_options = "hover",
                full_width = F,
                position = "left")
term estimate conf.int statistic df p.value
Intercept 2.73 [2.63, 2.83] 53.82 4786 < .001
Wrkclass obj 0.14 [0.01, 0.28] 2.07 4786 .039
Class zs 0.22 [0.19, 0.25] 14.56 4786 < .001
Wrkclass obj \(\times\) Class zs -0.05 [-0.09, -0.01] -2.48 4786 .013
interact_plot(m1,
              pred = "class_zs",
              modx = "wrkclass_obj")

Ok. Class zero-sum matters a lot. And it matters more for those who are not objectively in the working class. That makes sense. I’m guessing this interaction would flow through subjective social class, but oh man, I don’t want to do that mediation model.

Linear model 5D

Let’s add ideology as a control (and others) - I’m sure that’ll explain away a lot of the variance.

Outcome: Minimum wage support;
Predictor: interaction of objective class and class zero-sum beliefs Controls: Gender, race, age, political ideology

m1 <- lm(minwage_R ~ wrkclass_obj*class_zs + gender + race + age + ideo,data = df_anes)

apa_lm <- apa_print(m1)
kbl(apa_lm$table) %>% 
  kable_styling(bootstrap_options = "hover",
                full_width = F,
                position = "left")
term estimate conf.int statistic df p.value
Intercept 3.60 [3.39, 3.80] 34.68 3812 < .001
Wrkclass obj 0.04 [-0.10, 0.18] 0.61 3812 .543
Class zs 0.11 [0.07, 0.14] 6.65 3812 < .001
Gendernonbinary 0.08 [-0.17, 0.33] 0.60 3812 .550
Genderother 0.22 [-0.29, 0.72] 0.84 3812 .400
Genderwoman 0.14 [0.09, 0.19] 5.74 3812 < .001
Raceblack,non-hisp 0.15 [-0.01, 0.31] 1.85 3812 .065
Racehisp 0.14 [-0.01, 0.30] 1.80 3812 .072
Racemultiracial,non-hisp 0.10 [-0.08, 0.29] 1.10 3812 .272
Racenative,non-hisp 0.17 [-0.22, 0.57] 0.85 3812 .394
Racewhite,non-hisp 0.00 [-0.14, 0.13] -0.01 3812 .991
Age 0.00 [0.00, 0.00] 2.23 3812 .026
Ideo -0.18 [-0.20, -0.16] -21.66 3812 < .001
Wrkclass obj \(\times\) Class zs 0.00 [-0.04, 0.04] 0.04 3812 .969

Ok. The interaction is gone. All that remains is class zsb’s.

Linear model 5E

min.wage.support ~ class_zsb*subjective_class + objective_class

m1 <- lm(minwage_R ~ class_zs*class_subjbin + wrkclass_obj,data = df_anes)

apa_lm <- apa_print(m1)
kbl(apa_lm$table) %>% 
  kable_styling(bootstrap_options = "hover",
                full_width = F,
                position = "left")
term estimate conf.int statistic df p.value
Intercept 2.78 [2.69, 2.87] 61.11 4781 < .001
Class zs 0.20 [0.17, 0.23] 14.69 4781 < .001
Class subjbin 0.15 [0.01, 0.28] 2.05 4781 .041
Wrkclass obj -0.04 [-0.09, 0.01] -1.69 4781 .091
Class zs \(\times\) Class subjbin -0.02 [-0.06, 0.02] -1.17 4781 .243
interact_plot(m1,
              pred = "class_zs",
              modx = "class_subjbin")

Linear model 5F

min.wage.support ~ class_zsb* objective_class + subjective _class

m1 <- lm(minwage_R ~ class_zs*wrkclass_obj + class_subjbin,data = df_anes)

apa_lm <- apa_print(m1)
kbl(apa_lm$table) %>% 
  kable_styling(bootstrap_options = "hover",
                full_width = F,
                position = "left")
term estimate conf.int statistic df p.value
Intercept 2.73 [2.63, 2.83] 53.68 4781 < .001
Class zs 0.22 [0.19, 0.25] 14.27 4781 < .001
Wrkclass obj 0.11 [-0.02, 0.25] 1.64 4781 .101
Class subjbin 0.07 [0.02, 0.12] 2.61 4781 .009
Class zs \(\times\) Wrkclass obj -0.05 [-0.09, -0.01] -2.42 4781 .015
interact_plot(m1,
              pred = "class_zs",
              modx = "wrkclass_obj")

Mediation

Mediation model 1

Predictor: Class Zero-Sum
Mediator: Class
Outcome: Minimum wage support

m1 <- psych::mediate(minwage_R ~ class_zs + (class_num),data = df_anes,std = T,n.iter = 10000)

beta coefficients are standardized

a = -0.15 (p = 0)
b = -0.02 (p = 0.16)
c = 0.26 (p = 0)
c’= 0.26 (p = 0)

Mediation model 2

Predictor: Class
Mediator: Class Zero-Sum
Outcome: Minimum wage support

m1 <- psych::mediate(minwage_R ~ class_num + (class_zs),data = df_anes,std = T,n.iter = 10000)


a = -0.15 (p = 0)
b = 0.26 (p = 0)
c = -0.06 (p = 0)
c’= -0.02 (p = 0.16)