options(repos = c(CRAN = "https://cran.rstudio.com"))
# Install necessary packages if you haven't already
install.packages(c("haven", "fst"), repos='https://cran.rstudio.com')
## Installing packages into 'C:/Users/quinc/AppData/Local/R/win-library/4.3'
## (as 'lib' is unspecified)
## package 'haven' successfully unpacked and MD5 sums checked
## Warning: cannot remove prior installation of package 'haven'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): problem copying
## C:\Users\quinc\AppData\Local\R\win-library\4.3\00LOCK\haven\libs\x64\haven.dll
## to C:\Users\quinc\AppData\Local\R\win-library\4.3\haven\libs\x64\haven.dll:
## Permission denied
## Warning: restored 'haven'
## package 'fst' successfully unpacked and MD5 sums checked
## Warning: cannot remove prior installation of package 'fst'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): problem copying
## C:\Users\quinc\AppData\Local\R\win-library\4.3\00LOCK\fst\libs\x64\fst.dll to
## C:\Users\quinc\AppData\Local\R\win-library\4.3\fst\libs\x64\fst.dll: Permission
## denied
## Warning: restored 'fst'
##
## The downloaded binary packages are in
## C:\Users\quinc\AppData\Local\Temp\RtmpMDROqd\downloaded_packages
# Load the packages
library(haven)
## Warning: package 'haven' was built under R version 4.3.3
library(fst)
## Warning: package 'fst' was built under R version 4.3.3
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(ggplot2)
# List of packages
packages <- c("tidyverse", "infer", "fst", "modelsummary", "effects", "survey", "MASS", "aod", "interactions", "kableExtra", "flextable", "scales") # add any you need here
# Install packages if they aren't installed already
new_packages <- packages[!(packages %in% installed.packages()[,"Package"])]
if(length(new_packages)) install.packages(new_packages)
# Load the packages
lapply(packages, library, character.only = TRUE)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ lubridate 1.9.3 ✔ tibble 3.2.1
## ✔ purrr 1.0.2 ✔ tidyr 1.3.0
## ✔ readr 2.1.5
## ── 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
## Warning: package 'infer' was built under R version 4.3.3
## Warning: package 'effects' was built under R version 4.3.3
## Loading required package: carData
## Warning: package 'carData' was built under R version 4.3.3
## lattice theme set by effectsTheme()
## See ?effectsTheme for details.
## Warning: package 'survey' was built under R version 4.3.3
## Loading required package: grid
## Loading required package: Matrix
##
## Attaching package: 'Matrix'
##
## The following objects are masked from 'package:tidyr':
##
## expand, pack, unpack
##
## Loading required package: survival
##
## Attaching package: 'survey'
##
## The following object is masked from 'package:graphics':
##
## dotchart
##
##
## Attaching package: 'MASS'
##
## The following object is masked from 'package:dplyr':
##
## select
## Warning: package 'aod' was built under R version 4.3.3
##
## Attaching package: 'aod'
##
## The following object is masked from 'package:survival':
##
## rats
## Warning: package 'interactions' was built under R version 4.3.3
##
## Attaching package: 'kableExtra'
##
## The following object is masked from 'package:dplyr':
##
## group_rows
## Warning: package 'flextable' was built under R version 4.3.3
##
## Attaching package: 'flextable'
##
## The following objects are masked from 'package:kableExtra':
##
## as_image, footnote
##
## The following object is masked from 'package:purrr':
##
## compose
##
##
## Attaching package: 'scales'
##
## The following object is masked from 'package:purrr':
##
## discard
##
## The following object is masked from 'package:readr':
##
## col_factor
## [[1]]
## [1] "lubridate" "forcats" "stringr" "purrr" "readr" "tidyr"
## [7] "tibble" "tidyverse" "ggplot2" "dplyr" "fst" "haven"
## [13] "stats" "graphics" "grDevices" "utils" "datasets" "methods"
## [19] "base"
##
## [[2]]
## [1] "infer" "lubridate" "forcats" "stringr" "purrr" "readr"
## [7] "tidyr" "tibble" "tidyverse" "ggplot2" "dplyr" "fst"
## [13] "haven" "stats" "graphics" "grDevices" "utils" "datasets"
## [19] "methods" "base"
##
## [[3]]
## [1] "infer" "lubridate" "forcats" "stringr" "purrr" "readr"
## [7] "tidyr" "tibble" "tidyverse" "ggplot2" "dplyr" "fst"
## [13] "haven" "stats" "graphics" "grDevices" "utils" "datasets"
## [19] "methods" "base"
##
## [[4]]
## [1] "modelsummary" "infer" "lubridate" "forcats" "stringr"
## [6] "purrr" "readr" "tidyr" "tibble" "tidyverse"
## [11] "ggplot2" "dplyr" "fst" "haven" "stats"
## [16] "graphics" "grDevices" "utils" "datasets" "methods"
## [21] "base"
##
## [[5]]
## [1] "effects" "carData" "modelsummary" "infer" "lubridate"
## [6] "forcats" "stringr" "purrr" "readr" "tidyr"
## [11] "tibble" "tidyverse" "ggplot2" "dplyr" "fst"
## [16] "haven" "stats" "graphics" "grDevices" "utils"
## [21] "datasets" "methods" "base"
##
## [[6]]
## [1] "survey" "survival" "Matrix" "grid" "effects"
## [6] "carData" "modelsummary" "infer" "lubridate" "forcats"
## [11] "stringr" "purrr" "readr" "tidyr" "tibble"
## [16] "tidyverse" "ggplot2" "dplyr" "fst" "haven"
## [21] "stats" "graphics" "grDevices" "utils" "datasets"
## [26] "methods" "base"
##
## [[7]]
## [1] "MASS" "survey" "survival" "Matrix" "grid"
## [6] "effects" "carData" "modelsummary" "infer" "lubridate"
## [11] "forcats" "stringr" "purrr" "readr" "tidyr"
## [16] "tibble" "tidyverse" "ggplot2" "dplyr" "fst"
## [21] "haven" "stats" "graphics" "grDevices" "utils"
## [26] "datasets" "methods" "base"
##
## [[8]]
## [1] "aod" "MASS" "survey" "survival" "Matrix"
## [6] "grid" "effects" "carData" "modelsummary" "infer"
## [11] "lubridate" "forcats" "stringr" "purrr" "readr"
## [16] "tidyr" "tibble" "tidyverse" "ggplot2" "dplyr"
## [21] "fst" "haven" "stats" "graphics" "grDevices"
## [26] "utils" "datasets" "methods" "base"
##
## [[9]]
## [1] "interactions" "aod" "MASS" "survey" "survival"
## [6] "Matrix" "grid" "effects" "carData" "modelsummary"
## [11] "infer" "lubridate" "forcats" "stringr" "purrr"
## [16] "readr" "tidyr" "tibble" "tidyverse" "ggplot2"
## [21] "dplyr" "fst" "haven" "stats" "graphics"
## [26] "grDevices" "utils" "datasets" "methods" "base"
##
## [[10]]
## [1] "kableExtra" "interactions" "aod" "MASS" "survey"
## [6] "survival" "Matrix" "grid" "effects" "carData"
## [11] "modelsummary" "infer" "lubridate" "forcats" "stringr"
## [16] "purrr" "readr" "tidyr" "tibble" "tidyverse"
## [21] "ggplot2" "dplyr" "fst" "haven" "stats"
## [26] "graphics" "grDevices" "utils" "datasets" "methods"
## [31] "base"
##
## [[11]]
## [1] "flextable" "kableExtra" "interactions" "aod" "MASS"
## [6] "survey" "survival" "Matrix" "grid" "effects"
## [11] "carData" "modelsummary" "infer" "lubridate" "forcats"
## [16] "stringr" "purrr" "readr" "tidyr" "tibble"
## [21] "tidyverse" "ggplot2" "dplyr" "fst" "haven"
## [26] "stats" "graphics" "grDevices" "utils" "datasets"
## [31] "methods" "base"
##
## [[12]]
## [1] "scales" "flextable" "kableExtra" "interactions" "aod"
## [6] "MASS" "survey" "survival" "Matrix" "grid"
## [11] "effects" "carData" "modelsummary" "infer" "lubridate"
## [16] "forcats" "stringr" "purrr" "readr" "tidyr"
## [21] "tibble" "tidyverse" "ggplot2" "dplyr" "fst"
## [26] "haven" "stats" "graphics" "grDevices" "utils"
## [31] "datasets" "methods" "base"
data <- read_spss("romania_data.sav")
write_fst(data, "romania_data.fst")
romania_data <- read.fst("romania_data.fst")
romania_data <- read.fst("romania_data.fst")
romania_data_cleaned <- romania_data %>%
mutate(
gndr = case_when(
gndr == 1 ~ "Male",
gndr == 2 ~ "Female",
TRUE ~ NA_character_
),
lrscale = as.numeric(lrscale),
educ.ba = case_when(
essround < 5 & edulvla == 5 ~ "BA or more",
TRUE ~ "No BA"
)
) %>%
filter(
!is.na(gndr), !is.na(educ.ba), !is.na(trstplt), !is.na(lrscale) # Now filter out the NA values
)
num_obs <- nrow(romania_data_cleaned )
print(paste("Number of observations", num_obs))
## [1] "Number of observations 47015"
romania_data <- read.fst("romania_data.fst")
## Calculating Descriptive Statistics for Trust in Parliament (trstplt)
trstplt_stats <- romania_data %>%
filter(!is.na(trstplt)) %>% # Ensure you're only including non-NA values
summarise(
mean_trstplt = mean(trstplt), # Calculate mean
sd_trstplt = sd(trstplt) # Calculate standard deviation
)
## Output trstplt statistics
print(trstplt_stats)
## mean_trstplt sd_trstplt
## 1 3.275472 2.423905
## Calculating Descriptive Statistics for Left-Right Scale (lrscale)
# First, ensure the lrscale is properly cleaned and numeric
romania_data <- romania_data %>%
mutate(lrscale = as.numeric(lrscale)) %>% # Convert to numeric if not already
filter(!is.na(lrscale) & lrscale <= 10) # Exclude any NA or invalid values
lrscale_stats <- romania_data %>%
summarise(
mean_lrscale = mean(lrscale), # Calculate mean
sd_lrscale = sd(lrscale) # Calculate standard deviation
)
## Output lrscale statistics
print(lrscale_stats)
## mean_lrscale sd_lrscale
## 1 5.1991 2.278228
##LRSCALE##
romania_data <- romania_data %>%
# Filter for France
mutate(
gndr = case_when(
gndr == 1 ~ "Male",
gndr == 2 ~ "Female",
TRUE ~ NA_character_ # Set anything that is not 1 or 2 to NA
),
lrscale = case_when(
lrscale %in% 0:3 ~ "Left", # Left-wing (0 to 3)
lrscale %in% 7:10 ~ "Right", # Right-wing (7 to 10)
TRUE ~ NA_character_ # Moderate (4, 5, 6) and special codes (77, 88, 99) set to NA
)
)
TASK 4 EXPLANATION
Calculate the left right party percentages by filtering the left right scale and gender.
lrscale_percentages <- romania_data %>% # Begin with the dataset 'france_data'
filter(!is.na(lrscale), !is.na(gndr)) %>% # Filter out rows where 'lrscale' or 'gender' is NA (missing data)
group_by(gndr, lrscale) %>% # Group the data by 'gender' and 'lrscale' categories
summarise(count = n(), .groups = 'drop') %>% # Summarise each group to get counts, and then drop groupings
mutate(percentage = count / sum(count) * 100) # Calculate percentage for each group by dividing count by total count and multiplying by 100
lrscale_percentages # The resulting dataframe
## # A tibble: 4 × 4
## gndr lrscale count percentage
## <chr> <chr> <int> <dbl>
## 1 Female Left 5283 23.0
## 2 Female Right 6444 28.1
## 3 Male Left 4800 20.9
## 4 Male Right 6433 28.0
TASK 4 ANSWER
Visualization
# Create a ggplot object for horizontal bar chart with the specified style
lrscale_plot_v2 <- ggplot(lrscale_percentages,
aes(x = percentage, # Use percentage directly
y = reorder(gndr, -percentage), # Order bars within each gender
fill = gndr)) + # Fill color based on Gender
# Create horizontal bar chart
geom_col() + # Draws the bars using the provided data
coord_flip() + # Flip coordinates to make bars horizontal
# Remove fill color legend
guides(fill = "none") + # Removes legend for the fill aesthetic
# Split the plot based on Political Orientation
facet_wrap(~ lrscale, nrow = 1) + # Separate plots for Left/Right
# Labels and titles for the plot
labs(x = "Percentage of Respondents", # X-axis label
y = NULL, # Remove Y-axis label
title = "Political Orientation by Gender", # Main title
subtitle = "Comparing the percentage distribution of left vs. right for Romania (2008)") + # Subtitle
# Adjust visual properties of the plot
theme(plot.title = element_text(size = 16, face = "bold"), # Format title
plot.subtitle = element_text(size = 12), # Format subtitle
axis.title.y = element_blank(), # Remove Y-axis title
legend.position = "bottom") # Position the legend at the bottom
# Display the ggplot object
lrscale_plot_v2
##TRUST IN PARLIMENT##
romania_data <- read.fst("romania_data.fst")
romania_data <- romania_data %>%
# Filter for France
mutate(
gndr = case_when(
gndr == 1 ~ "Male",
gndr == 2 ~ "Female",
TRUE ~ NA_character_ # Set anything that is not 1 or 2 to NA
),
trstplt = ifelse(trstplt %in% c(77, 88, 99), NA, trstplt), # set values 77, 88, and 99 to NA.
)
table(romania_data$trstplt) # if there are values that are not supposed to be there (e.g., 77, 88, 99 in this case), then we need to deal with it
##
## 0 1 2 3 4 5 6 7 8 9 10
## 10387 5651 6563 7123 6395 9101 4565 3387 1562 388 332
trust_percentages <- romania_data %>%
filter(!is.na(trstplt), !is.na(gndr)) %>% # Filter out missing data
count(gndr, trstplt) %>% # Count the number of responses by gender and trust in politics
group_by(gndr) %>% # Group by gender
mutate(percentage = n / sum(n) * 100) # Calculate percentage within each gender
trust_plot <- ggplot(trust_percentages, aes(x = trstplt, y = percentage, fill = gndr)) +
geom_col() +
coord_flip() + # Flip coordinates to make bars horizontal
facet_wrap(~ gndr, nrow = 1, scales = "free_y") + # Separate plots for each gender
labs(x = "Trust in Politics Level", y = "Percentage of Respondents", title = "Trust in Parliament by Gender in Romania (2008)") +
theme_minimal() +
scale_fill_manual(values = c("Male" = "blue", "Female" = "red")) # Set colors for genders
# Display the plot
trust_plot
##BA OR NO BA##
romania_data <- read.fst("romania_data.fst")
romania_data <- romania_data %>%
mutate(
gndr = case_when(
gndr == 1 ~ "Male",
gndr == 2 ~ "Female",
TRUE ~ NA_character_
),
educ.ba = case_when(
essround < 5 & edulvla == 5 ~ "BA or more",
TRUE ~ "No BA"
)
) %>%
filter(!is.na(gndr) & !is.na(educ.ba))
education_by_gender <- romania_data %>%
group_by(gndr, educ.ba) %>%
summarise(count = n(), .groups = 'drop') %>%
mutate(percentage = count / sum(count) * 100)
education_plot <- ggplot(education_by_gender, aes(x = educ.ba, y = count, fill = educ.ba)) +
geom_bar(stat = "identity", position = "dodge") +
facet_wrap(~gndr) +
labs(title = "Educational Attainment by Gender in Romania (2008)",
x = "Educational Level",
y = "Count of Respondents") +
scale_fill_manual(values = c("BA or more" ="Green", "No BA" = "Yellow")) +
theme_minimal()
education_plot
##GNDR X TRSTPLT##
romania_data <- read.fst("romania_data.fst")
romania_data <- romania_data %>%
mutate(
# Clean 'trstplt' values
trstplt = ifelse(trstplt %in% c(77, 88, 99), NA, trstplt),
# Recode 'gndr'
gndr = case_when(
gndr == 1 ~ "Male",
gndr == 2 ~ "Female",
gndr == 9 ~ NA_character_, # Assuming '9' is a code for missing data
TRUE ~ as.character(gndr)
),
# Recode 'edulvla' to 'educ.ba'
educ.ba = case_when(
essround < 5 & edulvla == 5 ~ "BA or more", # Assuming '5' indicates bachelor's degree or higher for rounds < 5
TRUE ~ "No BA" # All other cases are considered 'No BA'
),
# Clean 'edulvla' values
edulvla = ifelse(edulvla %in% c(77, 88), NA_integer_, edulvla)
) %>%
mutate(
# Force 'educ.ba' to be treated as character to avoid factor conversion issues in ggplot
educ.ba = as.character(educ.ba)
) %>%
# Remove rows with missing data for the analysis
filter(!is.na(gndr), !is.na(educ.ba), !is.na(trstplt))
test_stat <- romania_data %>%
specify(explanatory = gndr, # change variable name for explanatory variable
response = trstplt) %>% # change variable name for outcome of interest
hypothesize(null = "independence") %>%
calculate(stat = "diff in means", order = c("Female", "Male"))
## Message: The independence null hypothesis does not inform calculation of the
## observed statistic (a difference in means) and will be ignored.
print(test_stat$stat)
## [1] -0.04490246
null_distribution <- romania_data %>%
specify(response = trstplt, explanatory = gndr) %>%
hypothesize(null = "independence") %>%
generate(reps = 1000, type = "permute") %>%
calculate(stat = "diff in means", order = c("Female", "Male"))
p_val <- null_distribution %>%
get_pvalue(obs_stat = test_stat, direction = "two-sided")
p_val
## # A tibble: 1 × 1
## p_value
## <dbl>
## 1 0.024
null_distribution %>%
visualize() +
shade_p_value(obs_stat = test_stat, direction = "two-sided")
null_distribution
## Response: trstplt (numeric)
## Explanatory: gndr (factor)
## Null Hypothesis: independence
## # A tibble: 1,000 × 2
## replicate stat
## <int> <dbl>
## 1 1 -0.00202
## 2 2 0.0324
## 3 3 0.0266
## 4 4 -0.0417
## 5 5 -0.0136
## 6 6 0.00445
## 7 7 0.00329
## 8 8 -0.00231
## 9 9 -0.0182
## 10 10 0.0433
## # ℹ 990 more rows
##GNDR X LRSCALE##
romania_data <- read.fst("romania_data.fst")
romania_data <- romania_data %>%
mutate(
gndr = case_when(
gndr == 1 ~ "Male",
gndr == 2 ~ "Female",
TRUE ~ NA_character_ # Set anything that is not 1 or 2 to NA
),
LR = case_when(
lrscale %in% 0:3 ~ "Left",
lrscale %in% 7:10 ~ "Right",
lrscale %in% 4:6 ~ "Moderate",
lrscale %in% c(77, 88, 99) ~ NA_character_
)
) %>%
# Remove rows with missing data for the analysis
filter(!is.na(gndr), !is.na(lrscale))
##MODELS for GNDR & TRSPLT##
romania_data <- read.fst("romania_data.fst")
Renaming dataset to df.
df <- romania_data
Note: you have both df and france_data which contain the french data (same observations, under different names). So you can always revert back to france_data if needed
From ess website:
For data collection the ess uses strictly probability-based samples. Every element in the ess target population should therefore have a greater than zero probability of being included into the sample. When analysing ess data estimates, the likelihood of each respondent to be part of the sample should also be taken into account - which means that the most accurate estimates will be obtained only after weighting the data.
df$weight <- df$dweight * df$pweight
survey_design <- svydesign(ids = ~1, data = df, weights = ~weight)
We will work with our populist attitudes scale based on Norris and Inglehart’s conceptualization and measurement again. So let’s run our code:
# Setting values greater than 10 to NA
df$trstplt <- ifelse(df$trstplt > 10, NA, df$trstplt)
df$trstprl <- ifelse(df$trstprl > 10, NA, df$trstprl)
df$trstprt <- ifelse(df$trstprt > 10, NA, df$trstprt)
df <- df %>%
# Filter for France
mutate(
gndr = case_when(
gndr == 1 ~ "Male",
gndr == 2 ~ "Female",
TRUE ~ NA_character_ # Set anything that is not 1 or 2 to NA
),
lrscale = case_when(
lrscale %in% 0:3 ~ "Left", # Left-wing (0 to 3)
lrscale %in% 7:10 ~ "Right", # Right-wing (7 to 10)
TRUE ~ NA_character_ # Moderate (4, 5, 6) and special codes (77, 88, 99) set to NA
),
educ.ba = case_when(
essround < 5 & edulvla == 5 ~ "BA or more",
TRUE ~ "No BA"
)
)
model1 <- lm(trstplt ~ gndr, data = df, weights = weight)
model2 <- lm(trstplt ~ gndr + educ.ba + lrscale, data = df, weights = weight)
model3 <- lm(trstplt ~ gndr*educ.ba, data = df, weights = weight)
modelsummary(
list(model1, model2, model3),
fmt = 1,
estimate = c( "{estimate} ({std.error}){stars}"),
statistic = NULL
)
| (1) | (2) | (3) | |
|---|---|---|---|
| (Intercept) | 3.2 (0.0)*** | 3.4 (0.0)*** | 3.2 (0.0)*** |
| gndrMale | 0.0 (0.0) | −0.1 (0.0)* | 0.1 (0.0)** |
| educ.baNo BA | −0.3 (0.0)*** | −0.1 (0.0)* | |
| lrscaleRight | 0.4 (0.0)*** | ||
| gndrMale × educ.baNo BA | −0.2 (0.0)*** | ||
| Num.Obs. | 55424 | 22699 | 55424 |
| R2 | 0.000 | 0.010 | 0.001 |
| R2 Adj. | 0.000 | 0.010 | 0.001 |
| AIC | 294237.7 | 120029.7 | 294164.9 |
| BIC | 294264.5 | 120069.8 | 294209.5 |
| Log.Lik. | −147115.864 | −60009.840 | −147077.454 |
| RMSE | 2.43 | 2.45 | 2.42 |
interaction_plot <- effect("gndr*educ.ba", model3, na.rm=TRUE)
plot(interaction_plot,
main="Interaction Effect of Gender and Education on Trust in Parliament",
xlab="Education Level",
ylab="Trust in Parliament")
interaction_plot
##
## gndr*educ.ba effect
## educ.ba
## gndr BA or more No BA
## Female 3.236436 3.168294
## Male 3.348610 3.077693
df$gndr <- factor(df$gndr, levels = c("Male", "Female"))
df$educ.ba <- factor(df$educ.ba, levels = c("No BA", "BA or more"))
ggplot(df, aes(x=educ.ba, y=trstplt, color=gndr)) +
stat_summary(fun=mean, geom="point", size=3) +
stat_summary(fun=mean, geom="line", aes(group=gndr), size=1) +
labs(title="Interaction Effect of Gender and Education on Trust in Parliament",
x="Education Level", y="Mean Trust in Parliament") +
theme_minimal()
## 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.
## Warning: Removed 1298 rows containing non-finite values (`stat_summary()`).
## Removed 1298 rows containing non-finite values (`stat_summary()`).