This project applies association rule mining to explore co-occurring social, political, and attitudinal patterns among Greek citizens, with a specific focus on low institutional trust.
Dataset: We use the data gathered from European Social Survey (ESS) Round 10. We treat each respondent as a “transaction” of traits.
Which social, political, and attitudinal characteristics tend to co-occur with low trust in political institutions?
We analyze data from Greece (ESS Round 10).
We select Greece from ESS Round 10 for the following reasons:
ESS data were imported from a locally downloaded .sav (spss format) file and cached as .rds to ensure reproducibility.
rds_path <- "data/ess10_gr_selected_numeric.rds"
sav_path <- "data/ESS country data - GR.sav"
if (file.exists(rds_path)) {
message("Loading cached RDS...")
df_selected <- readRDS(rds_path)
} else {
message("Reading SAV one-time and creating cache...")
if (!file.exists(sav_path)) {
stop("Put the file in data/ as: ESS country data - GR.sav")
}
gr_raw <- read_sav(sav_path) %>% clean_names()
df_selected <- gr_raw %>%
filter(essround == 10) %>%
select(any_of(c(
"trstprl","ppltrst",
"vote","lrscale",
"stflife",
"gndr","agea","eisced",
"imwbcnt","stfeco","netusoft"
))) %>%
zap_labels()
saveRDS(df_selected, rds_path)
}
dim(df_selected)
summary(df_selected)
## [1] 2799 11
## trstprl ppltrst vote lrscale
## Min. : 0.000 Min. : 0.000 Min. :1.000 Min. : 0.000
## 1st Qu.: 2.000 1st Qu.: 3.000 1st Qu.:1.000 1st Qu.: 4.000
## Median : 4.000 Median : 4.000 Median :1.000 Median : 5.000
## Mean : 4.286 Mean : 4.415 Mean :1.177 Mean : 5.269
## 3rd Qu.: 6.000 3rd Qu.: 6.000 3rd Qu.:1.000 3rd Qu.: 7.000
## Max. :10.000 Max. :10.000 Max. :3.000 Max. :10.000
## NA's :16 NA's :4 NA's :43 NA's :325
## stflife gndr agea eisced
## Min. : 0.000 Min. :1.000 Min. :15.00 Min. : 1.000
## 1st Qu.: 5.000 1st Qu.:1.000 1st Qu.:37.00 1st Qu.: 3.000
## Median : 7.000 Median :2.000 Median :50.00 Median : 4.000
## Mean : 6.364 Mean :1.523 Mean :50.38 Mean : 4.179
## 3rd Qu.: 8.000 3rd Qu.:2.000 3rd Qu.:63.00 3rd Qu.: 6.000
## Max. :10.000 Max. :2.000 Max. :89.00 Max. :55.000
## NA's :16 NA's :54 NA's :11
## imwbcnt stfeco netusoft
## Min. : 0.000 Min. : 0.000 Min. :1.000
## 1st Qu.: 3.000 1st Qu.: 2.000 1st Qu.:3.000
## Median : 5.000 Median : 4.000 Median :5.000
## Mean : 4.292 Mean : 3.808 Mean :3.972
## 3rd Qu.: 6.000 3rd Qu.: 5.000 3rd Qu.:5.000
## Max. :10.000 Max. :10.000 Max. :5.000
## NA's :40 NA's :9 NA's :5
| Variable | Description | Original Scale | Discretization Logic |
|---|---|---|---|
| Target Variable | |||
| trstprl | Trust in Parliament (Target) | 0–10 Likert | Low (0–3), Medium (4–6), High (7–10) |
| Attitudes & Ideology | |||
| stfeco | Satisfaction with Economy | 0–10 Likert | Low (0–3), Medium (4–6), High (7–10) |
| stflife | Life Satisfaction | 0–10 Likert | Low (0–3), Medium (4–6), High (7–10) |
| ppltrst | Generalized Social Trust | 0–10 Likert | Low (0–3), Medium (4–6), High (7–10) |
| imwbcnt | Attitude Toward Immigration | 0–10 Likert | Worse (0–3), Neutral (4–6), Better (7–10) |
| lrscale | Left–Right Ideological Position | 0–10 Left–Right | Left (0–3), Center (4–6), Right (7–10) |
| Demographics | |||
| agea | Age of Respondent | Continuous | Young (<30), Adult (30–59), Senior (60+) |
| eisced | Education Level (ISCED) | ISCED Categories | Low (Primary), Medium (Secondary), High (Tertiary) |
| gndr | Gender | Nominal | Male, Female |
| Behavior & Engagement | |||
| vote | Voted in Last National Election | Nominal | Yes, No, Not Eligible |
| netusoft | Internet Use Frequency | Ordinal (1–5) | Low (Never), Medium (Occasional), High (Daily) |
Derived Table from ESS Codebook
ESS survey variables use dedicated numeric codes for non-substantive responses (for example refusal, “don’t know”, or no answer). These responses do not reflect the underlying attitude/behavior being measured, so they were treated as missing values (NA) prior to discretization and transaction creation.
df_clean <- df_selected %>%
mutate(
trstprl = trstprl %>% na_if(77) %>% na_if(88) %>% na_if(99),
ppltrst = ppltrst %>% na_if(77) %>% na_if(88) %>% na_if(99),
lrscale = lrscale %>% na_if(77) %>% na_if(88) %>% na_if(99),
stflife = stflife %>% na_if(77) %>% na_if(88) %>% na_if(99),
stfeco = stfeco %>% na_if(77) %>% na_if(88) %>% na_if(99),
imwbcnt = imwbcnt %>% na_if(77) %>% na_if(88) %>% na_if(99),
eisced = eisced %>% na_if(77) %>% na_if(88) %>% na_if(99),
agea = na_if(agea, 999),
gndr = na_if(gndr, 9),
vote = vote %>% na_if(7) %>% na_if(8) %>% na_if(9),
netusoft = netusoft %>% na_if(7) %>% na_if(8) %>% na_if(9)
) %>%
drop_na()
cat("Rows before cleaning:", nrow(df_selected), "\n")
cat("Rows after cleaning :", nrow(df_clean), "\n")
cat("Share kept :", round(nrow(df_clean) / nrow(df_selected), 3), "\n")
## Rows before cleaning: 2799
## Rows after cleaning : 2350
## Share kept : 0.84
Discretization cutoffs were chosen a priori based on the ESS response scale and standard practice in survey analysis.
df_disc <- df_clean %>%
transmute(
# Consequent (target)
trust_parliament = case_when(
trstprl <= 3 ~ "Low",
trstprl <= 6 ~ "Medium",
trstprl >= 7 ~ "High",
.default = NA_character_
),
# Institutional / Social trust
social_trust = case_when(
ppltrst <= 3 ~ "Low",
ppltrst <= 6 ~ "Medium",
ppltrst >= 7 ~ "High",
.default = NA_character_
),
# Political behavior
voted = case_when(
vote == 1 ~ "Yes",
vote == 2 ~ "No",
vote == 3 ~ "NotEligible",
.default = NA_character_
),
# Political orientation
ideology = case_when(
lrscale <= 3 ~ "Left",
lrscale <= 6 ~ "Center",
lrscale >= 7 ~ "Right",
.default = NA_character_
),
# Well-being and economy
life_satisfaction = case_when(
stflife <= 3 ~ "Low",
stflife <= 6 ~ "Medium",
stflife >= 7 ~ "High",
.default = NA_character_
),
econ_satisfaction = case_when(
stfeco <= 3 ~ "Low",
stfeco <= 6 ~ "Medium",
stfeco >= 7 ~ "High",
.default = NA_character_
),
# Immigration attitudes
immigration_attitude = case_when(
imwbcnt <= 3 ~ "Worse",
imwbcnt <= 6 ~ "Neutral",
imwbcnt >= 7 ~ "Better",
.default = NA_character_
),
# Digital engagement
internet_use = case_when(
netusoft <= 2 ~ "Low",
netusoft == 3 ~ "Medium",
netusoft >= 4 ~ "High",
.default = NA_character_
),
# Demographics
gender = case_when(
gndr == 1 ~ "Male",
gndr == 2 ~ "Female",
.default = NA_character_
),
age_group = case_when(
agea < 30 ~ "Young",
agea < 60 ~ "Adult",
agea >= 60 ~ "Senior",
.default = NA_character_
),
education = case_when(
eisced %in% c(1, 2) ~ "Low",
eisced %in% c(3, 4, 5, 0, 55) ~ "Medium",
eisced %in% c(6, 7) ~ "High",
.default = NA_character_
)
) %>%
drop_na() %>%
mutate(across(everything(), as.factor))
# Convert to transactions for arules
trans <- as(df_disc, "transactions")
summary(trans)
itemFrequencyPlot(trans, topN = 15, type = "relative")
summary(size(trans))
## transactions as itemMatrix in sparse format with
## 2350 rows (elements/itemsets/transactions) and
## 32 columns (items) and a density of 0.34375
##
## most frequent items:
## voted=Yes internet_use=High ideology=Center
## 2062 1725 1313
## age_group=Adult life_satisfaction=High (Other)
## 1310 1267 18173
##
## element (itemset/transaction) length distribution:
## sizes
## 11
## 2350
##
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 11 11 11 11 11 11
##
## includes extended item information - examples:
## labels variables levels
## 1 trust_parliament=High trust_parliament High
## 2 trust_parliament=Low trust_parliament Low
## 3 trust_parliament=Medium trust_parliament Medium
##
## includes extended transaction information - examples:
## transactionID
## 1 1
## 2 2
## 3 3
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 11 11 11 11 11 11
Several items have high prevalence (e.g., voted=Yes), which may generate trivial high-confidence rules; therefore lift and redundancy filtering are used to prioritize non-random, informative associations.
Each respondent contributes a similar number of items due to controlled discretization of survey variables.
Each respondent is treated as a transaction consisting of discretized socio-political traits; Apriori discovers frequent co-occurring trait combinations associated with low trust in parliament.
We first inspect the prevalence of the target item to ensure that the minimum support threshold allows rules involving the chosen consequent. If the target is very common, lift-based filtering becomes especially important to avoid trivial associations.
freq_low <- itemFrequency(trans)["trust_parliament=Low"]
freq_high <- itemFrequency(trans)["trust_parliament=High"]
cat("Support of trust_parliament=Low :", round(freq_low, 3), "\n")
cat("Support of trust_parliament=High:", round(freq_high, 3), "\n")
## Support of trust_parliament=Low : 0.355
## Support of trust_parliament=High: 0.186
We examine how the number of rules varies with the support threshold to justify the final choice and avoid mining noise or overly restrictive models.
support_levels <- c(0.02, 0.03, 0.04, 0.05, 0.06)
rules_count <- sapply(support_levels, function(sup) {
r <- apriori(
trans,
parameter = list(support = sup, confidence = 0.5, minlen = 2, maxlen = 4),
appearance = list(rhs = "trust_parliament=Low", default = "lhs"),
control = list(verbose = FALSE)
)
length(r)
})
tuning_df <- tibble(
Support = support_levels,
Number_of_Rules = rules_count
)
kable(
tuning_df,
digits=3,
caption = "Sensitivity analysis: number of association rules as a function of the support threshold."
) %>%
kable_styling(full_width = FALSE, bootstrap_options = c("striped", "hover")) %>%
scroll_box(width = "100%")
| Support | Number_of_Rules |
|---|---|
| 0.02 | 248 |
| 0.03 | 183 |
| 0.04 | 141 |
| 0.05 | 114 |
| 0.06 | 94 |
As the support threshold increases, the number of discovered rules declines rapidly. A support of 0.03 provides a balanced trade-off, retaining sufficient structure for meaningful analysis while avoiding an explosion of low-frequency rules. This choice is consistent with subsequent filtering steps, including redundancy removal, confidence tightening, and rule-length constraints. Lower thresholds risk capturing noise, whereas higher thresholds may suppress informative but less frequent patterns.
To assess the robustness of the mined association rules, we conducted an 80/20 train–test split of the transactional dataset. Association rules were mined exclusively on the training set, and the strongest rules (ranked by lift) were evaluated on the held-out test set using confidence as the stability criterion.
set.seed(47)
# 80/20 split
train_idx <- sample(seq_along(trans), size = floor(0.8 * length(trans)))
trans_train <- trans[train_idx]
trans_test <- trans[-train_idx]
# Mine rules on train
rules_train <- apriori(
trans_train,
parameter = list(support = 0.03, confidence = 0.60, minlen = 2, maxlen = 4),
appearance = list(rhs = "trust_parliament=Low", default = "lhs"),
control = list(verbose = FALSE)
)
# Remove redundant rules
rules_train <- rules_train[!is.redundant(rules_train)]
The rules were mined and are processed to the validation tests.
The validation section consist of several independent validation indicators.
# Select top rules to validate by the train lift
top_rules <- head(sort(rules_train, by = "lift"), 10)
# Evaluate stability on test
test_conf <- interestMeasure(top_rules, measure = "confidence", transactions = trans_test,reuse=FALSE)
stability_tbl <- tibble(
rule = labels(top_rules),
support_train = quality(top_rules)$support,
conf_train = quality(top_rules)$confidence,
lift_train = quality(top_rules)$lift,
conf_test = as.numeric(test_conf)
) %>%
arrange(desc(lift_train))
kable(stability_tbl, digits = 3, caption = "Train (80%) vs Test (20%) stability check for top-10 lift rules (RHS = Low Trust).")%>%
kable_styling(full_width = FALSE, bootstrap_options = c("striped", "hover")) %>%
scroll_box(width = "100%")
| rule | support_train | conf_train | lift_train | conf_test |
|---|---|---|---|---|
| {life_satisfaction=Low,econ_satisfaction=Low} => {trust_parliament=Low} | 0.035 | 0.747 | 2.069 | 0.680 |
| {social_trust=Low,econ_satisfaction=Low,immigration_attitude=Worse} => {trust_parliament=Low} | 0.072 | 0.707 | 1.957 | 0.578 |
| {econ_satisfaction=Low,immigration_attitude=Worse,gender=Female} => {trust_parliament=Low} | 0.082 | 0.703 | 1.947 | 0.551 |
| {ideology=Center,econ_satisfaction=Low,immigration_attitude=Worse} => {trust_parliament=Low} | 0.088 | 0.693 | 1.920 | 0.554 |
| {ideology=Right,econ_satisfaction=Low,immigration_attitude=Worse} => {trust_parliament=Low} | 0.034 | 0.692 | 1.917 | 0.556 |
| {econ_satisfaction=Low,immigration_attitude=Worse,education=Medium} => {trust_parliament=Low} | 0.074 | 0.688 | 1.905 | 0.545 |
| {life_satisfaction=Medium,econ_satisfaction=Low,immigration_attitude=Worse} => {trust_parliament=Low} | 0.069 | 0.688 | 1.904 | 0.536 |
| {econ_satisfaction=Low,immigration_attitude=Worse,internet_use=High} => {trust_parliament=Low} | 0.107 | 0.685 | 1.896 | 0.580 |
| {econ_satisfaction=Low,immigration_attitude=Worse,education=Low} => {trust_parliament=Low} | 0.043 | 0.681 | 1.885 | 0.520 |
| {voted=Yes,econ_satisfaction=Low,immigration_attitude=Worse} => {trust_parliament=Low} | 0.136 | 0.680 | 1.883 | 0.538 |
Generalization check: As expected, test-set confidence is lower than training confidence for all top rules; however, the deviations are moderate, indicating reasonable out-of-sample stability.
The most robust pattern is a broad dissatisfaction signal. In particular, the rule {life_satisfaction = Low, econ_satisfaction = Low} exhibits the smallest confidence drop and remains strongly predictive out of sample, well above the baseline prevalence of low trust (0.355).
In contrast, more specific rules that combine economic dissatisfaction with demographic or ideological attributes show larger confidence reductions, suggesting increased sensitivity to sampling variation. This indicates that while economic dissatisfaction is a stable core correlate of low institutional trust, adding demographic or ideological constraints tends to reduce generalizability.
The substantive structure of the rules remains consistent across train–test splits. Low economic satisfaction acts as the central anchor of low trust, with low life satisfaction, low generalized social trust, and pessimistic immigration attitudes appearing as reinforcing factors rather than independent drivers.
While lift captures relative departure from independence, leverage measures absolute deviation.
# Add leverage to rule quality
quality(rules_train) <- cbind(
quality(rules_train),
leverage = interestMeasure(rules_train, "leverage", trans_train)
)
inspect(head(sort(rules_train, by = "leverage"), 5))
## lhs rhs support confidence coverage lift count leverage
## [1] {econ_satisfaction=Low} => {trust_parliament=Low} 0.2712766 0.6049822 0.4484043 1.675061 510 0.10932634
## [2] {voted=Yes,
## econ_satisfaction=Low} => {trust_parliament=Low} 0.2356383 0.6093535 0.3867021 1.687164 443 0.09597301
## [3] {econ_satisfaction=Low,
## internet_use=High} => {trust_parliament=Low} 0.2085106 0.6212361 0.3356383 1.720065 392 0.08728808
## [4] {voted=Yes,
## econ_satisfaction=Low,
## internet_use=High} => {trust_parliament=Low} 0.1787234 0.6268657 0.2851064 1.735652 336 0.07575147
## [5] {econ_satisfaction=Low,
## immigration_attitude=Worse} => {trust_parliament=Low} 0.1510638 0.6745843 0.2239362 1.867774 284 0.07018476
In addition to lift, leverage was examined to assess absolute departures from statistical independence. Leverage quantifies how much more frequently a rule occurs than expected under independence, favoring rules with higher support. The top rules exhibit leverage values aproximately between 0.07 and 0.11, indicating substantial absolute co-occurrence beyond chance. Unlike Lift, which highlighted specific demographic profiles, Leverage indicates that ‘Economic Dissatisfaction’ is the dominant, broad-based driver of distrust in the population. The fact that {Econ_Satisfaction=Low} alone appears at the top (Leverage = 0.11) shows that it is a mass phenomenon, not a niche issue.
quality(rules_train) <- cbind(
quality(rules_train),
conviction = interestMeasure(rules_train, "conviction", trans_train)
)
inspect(head(sort(rules_train, by = "conviction"), 5))
## lhs rhs support confidence coverage lift count leverage conviction
## [1] {life_satisfaction=Low,
## econ_satisfaction=Low} => {trust_parliament=Low} 0.03457447 0.7471264 0.04627660 2.068627 65 0.01786074 2.526281
## [2] {social_trust=Low,
## econ_satisfaction=Low,
## immigration_attitude=Worse} => {trust_parliament=Low} 0.07180851 0.7068063 0.10159574 1.956989 135 0.03511515 2.178866
## [3] {econ_satisfaction=Low,
## immigration_attitude=Worse,
## gender=Female} => {trust_parliament=Low} 0.08191489 0.7031963 0.11648936 1.946994 154 0.03984241 2.152365
## [4] {ideology=Center,
## econ_satisfaction=Low,
## immigration_attitude=Worse} => {trust_parliament=Low} 0.08776596 0.6932773 0.12659574 1.919531 165 0.04204335 2.082760
## [5] {ideology=Right,
## econ_satisfaction=Low,
## immigration_attitude=Worse} => {trust_parliament=Low} 0.03351064 0.6923077 0.04840426 1.916846 63 0.01602846 2.076197
In addition to lift, conviction was considered as a complementary interest measure, as it captures the directional strength of implications. Conceptually, high conviction would indicate that the absence of key antecedents (e.g., economic dissatisfaction) substantially reduces the likelihood of low institutional trust, highlighting the asymmetric nature of such associations
We want to answer the question ‘Are rules we find niche or relevant?’. What fraction of respondents satisfy at least one of the top rules’ antecedents?
# Respondents covered by at least one of the top rules
cover_mat <- is.subset(lhs(top_rules), trans, sparse = FALSE)
covered_tx <- colSums(cover_mat) > 0
coverage_rate <- mean(covered_tx)
cat("Coverage of top rules:", round(coverage_rate, 3), "of respondents\n")
## Coverage of top rules: 0.243 of respondents
The top high-lift rules jointly cover 24.3% of respondents (at least one antecedent holds). This indicates the mined patterns are not purely niche: they describe a sizable minority of the sample.
Since confidence fluctuates, we verify the statistical dependence of the # {Life_Satisfaction=Low} -> {Trust=Low} rule using a Chi-Square test on the full dataset.
tbl_sig <- table(
Life_Sat_Low = df_disc$life_satisfaction == "Low", # Antecedent
Trust_Low = df_disc$trust_parliament == "Low" # Consequent
)
chisq_res <- chisq.test(tbl_sig)
cat("Chi-Square Test of Independence:\n")
print(tbl_sig) # Print the contingency table to show the counts
cat("\np-value:", chisq_res$p.value, "\n")
if(chisq_res$p.value < 0.05) {
cat("Result: Statistically significant association (p < 0.001).\n")
} else {
cat("Result: Not Significant.")
}
## Chi-Square Test of Independence:
## Trust_Low
## Life_Sat_Low FALSE TRUE
## FALSE 1470 745
## TRUE 46 89
##
## p-value: 5.47052e-14
## Result: Statistically significant association (p < 0.001).
top_tbl <- tibble(
rule = labels(top_rules),
support = quality(top_rules)$support,
confidence = quality(top_rules)$confidence,
lift = quality(top_rules)$lift
) %>% arrange(desc(lift))
kable(top_tbl, digits = 3, caption = "Top-10 rules ranked by lift (mined on training set).") %>%
kable_styling(full_width = FALSE, bootstrap_options = c("striped", "hover")) %>%
scroll_box(width = "100%")
| rule | support | confidence | lift |
|---|---|---|---|
| {life_satisfaction=Low,econ_satisfaction=Low} => {trust_parliament=Low} | 0.035 | 0.747 | 2.069 |
| {social_trust=Low,econ_satisfaction=Low,immigration_attitude=Worse} => {trust_parliament=Low} | 0.072 | 0.707 | 1.957 |
| {econ_satisfaction=Low,immigration_attitude=Worse,gender=Female} => {trust_parliament=Low} | 0.082 | 0.703 | 1.947 |
| {ideology=Center,econ_satisfaction=Low,immigration_attitude=Worse} => {trust_parliament=Low} | 0.088 | 0.693 | 1.920 |
| {ideology=Right,econ_satisfaction=Low,immigration_attitude=Worse} => {trust_parliament=Low} | 0.034 | 0.692 | 1.917 |
| {econ_satisfaction=Low,immigration_attitude=Worse,education=Medium} => {trust_parliament=Low} | 0.074 | 0.688 | 1.905 |
| {life_satisfaction=Medium,econ_satisfaction=Low,immigration_attitude=Worse} => {trust_parliament=Low} | 0.069 | 0.688 | 1.904 |
| {econ_satisfaction=Low,immigration_attitude=Worse,internet_use=High} => {trust_parliament=Low} | 0.107 | 0.685 | 1.896 |
| {econ_satisfaction=Low,immigration_attitude=Worse,education=Low} => {trust_parliament=Low} | 0.043 | 0.681 | 1.885 |
| {voted=Yes,econ_satisfaction=Low,immigration_attitude=Worse} => {trust_parliament=Low} | 0.136 | 0.680 | 1.883 |
plot(
rules_train,
measure = c("support", "confidence"),
shading = "lift"
)
The support–confidence scatter plot shaded by lift illustrates the trade-off between rule generality and strength. High-lift rules tend to occur at moderate support levels, indicating informative but non-trivial associations rather than tautological patterns.
We use a grouped matrix and a graph to see which variables cluster together.
# Grouped Matrix
plot(rules_train, method = "grouped", control = list(k = 15))
# Interactive Network Graph
plot(top_rules, method = "graph", engine = "htmlwidget")
The grouped matrix and rule network visualizations highlight the central role of economic dissatisfaction and its frequent co-occurrence with low life satisfaction, low social trust, and negative immigration attitudes. Variables related to demographic characteristics appear as secondary modifiers rather than primary drivers, reinforcing the interpretation that institutional distrust is rooted primarily in evaluative attitudes rather than fixed socio-demographic traits.
The most dominant antecedent across all top rules is Low
Economic Satisfaction (econ_satisfaction=Low). *
Insight: In the Greek context (ESS Round 10), political
trust appears to be heavily “performance-based.” Citizens do not simply
distrust the parliament due to abstract ideology; they distrust it
because they perceive the economic system is failing. *
Quantification: Rules involving low economic
satisfaction doubles the likelihood of low trust in parliament relative
to the baseline prevalence (lift ≈ 2.1), highlighting economic
evaluations as a key correlate of institutional distrust.
Beyond economic evaluations, low institutional trust co-occurs with broader dissatisfaction at both the personal and social level. Rules combining low life satisfaction or low generalized social trust with economic dissatisfaction consistently exhibit high lift values. This pattern indicates that distrust in political institutions is embedded in a wider syndrome of pessimism and disengagement rather than being an isolated political attitude. In substantive terms, respondents who are dissatisfied with economic conditions and simultaneously exhibit low trust in others tend to express particularly low confidence in parliamentary institutions.
Negative attitudes toward immigration frequently appear as reinforcing conditions in high-lift rules. When combined with economic dissatisfaction, pessimistic evaluations of immigration further increase the likelihood of low trust in parliament. This pattern indicates that institutional distrust is associated with broader negative evaluations of societal change and perceived threats.
While the association rules reveal strong patterns, the following limitations apply:
This study applied association rule mining to European Social Survey data to identify profiles associated with low trust in parliament in Greece. The results reveal a stable and coherent pattern: low economic satisfaction acts as the central anchor of institutional distrust, reinforced by low personal well-being, low generalized social trust, and pessimistic attitudes toward immigration. Importantly, validation revealed that while the core patterns of dissatisfaction persist across train–test splits, complex rules involving specific ideologies were prone to overfitting. This suggests that the robust driver of distrust is systemic performance failure, not demographic identity. Overall, the findings indicate that institutional distrust in Greece is embedded in broader dissatisfaction and evaluative pessimism rather than isolated demographic characteristics.
Data Source
European Social Survey ERIC. (2022). European Social Survey Round 10 (2020–2022) integrated file [Data set]. Sikt – Norwegian Agency for Shared Services in Education and Research. https://www.europeansocialsurvey.org
Other Sources
Hahsler, M., Grün, B., & Hornik, K. (2005). arules – A computational environment for mining association rules and frequent item sets. Journal of Statistical Software, 14(15), 1–25. https://doi.org/10.18637/jss.v014.i15
Hahsler, M. (2017). arulesViz: Interactive visualization of association rules with R. The R Journal, 9(2), 163–175. https://doi.org/10.32614/RJ-2017-047
European Social Survey ERIC. (n.d.). Methodology overview. European Social Survey. https://www.europeansocialsurvey.org/methodology/methodology-overview
# Core R info
print(R.version)
cat("\nPlatform:", R.version$platform, "\n")
cat("Running on:", R.version$os, "\n\n")
# Packages , versions loaded in this session
sessionInfo()
## _
## platform x86_64-w64-mingw32
## arch x86_64
## os mingw32
## crt ucrt
## system x86_64, mingw32
## status
## major 4
## minor 5.1
## year 2025
## month 06
## day 13
## svn rev 88306
## language R
## version.string R version 4.5.1 (2025-06-13 ucrt)
## nickname Great Square Root
##
## Platform: x86_64-w64-mingw32
## Running on: mingw32
##
## R version 4.5.1 (2025-06-13 ucrt)
## Platform: x86_64-w64-mingw32/x64
## Running under: Windows 11 x64 (build 22631)
##
## Matrix products: default
## LAPACK version 3.12.1
##
## locale:
## [1] LC_COLLATE=Turkish_Türkiye.utf8 LC_CTYPE=Turkish_Türkiye.utf8
## [3] LC_MONETARY=Turkish_Türkiye.utf8 LC_NUMERIC=C
## [5] LC_TIME=Turkish_Türkiye.utf8
##
## time zone: Europe/Warsaw
## tzcode source: internal
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] kableExtra_1.4.0 janitor_2.2.1 haven_2.5.5 knitr_1.51
## [5] arulesViz_1.5.4 arules_1.7.13 Matrix_1.7-3 lubridate_1.9.4
## [9] forcats_1.0.1 stringr_1.6.0 dplyr_1.1.4 purrr_1.2.0
## [13] readr_2.1.5 tidyr_1.3.1 tibble_3.3.0 ggplot2_4.0.0
## [17] tidyverse_2.0.0
##
## loaded via a namespace (and not attached):
## [1] gtable_0.3.6 xfun_0.54 bslib_0.9.0 htmlwidgets_1.6.4
## [5] visNetwork_2.1.4 ggrepel_0.9.6 lattice_0.22-7 tzdb_0.5.0
## [9] vctrs_0.6.5 tools_4.5.1 generics_0.1.4 ca_0.71.1
## [13] pkgconfig_2.0.3 RColorBrewer_1.1-3 S7_0.2.0 lifecycle_1.0.4
## [17] compiler_4.5.1 farver_2.1.2 textshaping_1.0.4 ggforce_0.5.0
## [21] codetools_0.2-20 graphlayouts_1.2.2 snakecase_0.11.1 seriation_1.5.8
## [25] htmltools_0.5.9 sass_0.4.10 yaml_2.3.10 pillar_1.11.1
## [29] jquerylib_0.1.4 MASS_7.3-65 cachem_1.1.0 iterators_1.0.14
## [33] viridis_0.6.5 foreach_1.5.2 TSP_1.2.6 tidyselect_1.2.1
## [37] digest_0.6.37 stringi_1.8.7 labeling_0.4.3 polyclip_1.10-7
## [41] fastmap_1.2.0 grid_4.5.1 cli_3.6.5 magrittr_2.0.4
## [45] ggraph_2.2.2 tidygraph_1.3.1 withr_3.0.2 scales_1.4.0
## [49] registry_0.5-1 timechange_0.3.0 rmarkdown_2.30 igraph_2.2.1
## [53] otel_0.2.0 gridExtra_2.3 hms_1.1.4 memoise_2.0.1
## [57] evaluate_1.0.5 viridisLite_0.4.2 rlang_1.1.6 Rcpp_1.1.0
## [61] glue_1.8.0 xml2_1.4.1 tweenr_2.0.3 svglite_2.2.2
## [65] rstudioapi_0.17.1 jsonlite_2.0.0 R6_2.6.1 systemfonts_1.3.1