Use cultural dimension labels

This commit is contained in:
aseimel
2026-06-15 15:18:30 +02:00
parent 9a16f3232f
commit 7643658b15
8 changed files with 36 additions and 35 deletions
+1 -1
View File
@@ -97,6 +97,6 @@ Original raw source files are not redistributed. Rebuilding inputs from raw file
The two position variables are scaled from 0 to 1: The two position variables are scaled from 0 to 1:
- `economic_lr`: economic left to economic right. - `economic_lr`: economic left to economic right.
- `galtan`: cosmopolitan/socially liberal to traditionalist/nationalist. - `galtan`: cultural cosmopolitan--traditionalist position.
Column definitions are in `metadata/data_dictionary.csv`. Column definitions are in `metadata/data_dictionary.csv`.
+1 -1
View File
@@ -33,7 +33,7 @@ The V4 Stan model (`stan_model_2dim_v4.stan`) uses these mappings to produce **i
3. **Expert data constrains individuals directly.** A CHES rating of CDU in 2019 maps to `theta[dim, rr_CDU_2019]` with no averaging. This is what identifies the *difference* between constituents. 3. **Expert data constrains individuals directly.** A CHES rating of CDU in 2019 maps to `theta[dim, rr_CDU_2019]` with no averaging. This is what identifies the *difference* between constituents.
4. **Identification depends on data availability:** 4. **Identification depends on data availability:**
- **Periods with individual expert data** (e.g., CHES 1999-2024): Constituent estimates separate meaningfully. CSU appears more conservative on galtan than CDU, matching known ground truth. - **Periods with individual expert data** (e.g., CHES 1999-2024): Constituent estimates separate meaningfully. CSU appears more traditionalist on the cultural dimension than CDU, matching known ground truth.
- **Periods without individual expert data** (e.g., 1950s-1990s): Only the shared manifesto constrains the mean. The random walk prior pulls constituents toward similar values, so CDU ≈ CSU with wide credible intervals on the gap. The estimates gradually differentiate as expert data appears. - **Periods without individual expert data** (e.g., 1950s-1990s): Only the shared manifesto constrains the mean. The random walk prior pulls constituents toward similar values, so CDU ≈ CSU with wide credible intervals on the gap. The estimates gradually differentiate as expert data appears.
5. **Backwards compatible.** With an empty `union_mapping.csv`, all observations have `n_const=1` and V4 reduces exactly to V3. 5. **Backwards compatible.** With an empty `union_mapping.csv`, all observations have `n_const=1` and V4 reduces exactly to V3.
+4 -4
View File
@@ -9,13 +9,13 @@ party_2d_election_year_panel_vN.csv.gz,union_party_id,Union or alliance PartyFac
party_2d_election_year_panel_vN.csv.gz,in_union,Union membership indicator,Indicator that the row is associated with a union or alliance,boolean,0;1,0,1,,indicator,,Alliance mapping,, party_2d_election_year_panel_vN.csv.gz,in_union,Union membership indicator,Indicator that the row is associated with a union or alliance,boolean,0;1,0,1,,indicator,,Alliance mapping,,
party_2d_election_year_panel_vN.csv.gz,pervote,Vote share,Vote share at the election year,numeric,,0,100,,percent,,Election metadata,, party_2d_election_year_panel_vN.csv.gz,pervote,Vote share,Vote share at the election year,numeric,,0,100,,percent,,Election metadata,,
party_2d_election_year_panel_vN.csv.gz,economic_lr,Economic left-right posterior mean,Posterior mean of economic left-right position,numeric,,0,1,,unit interval,0=left; 1=right,Posterior draws,Mean after inverse-logit transformation, party_2d_election_year_panel_vN.csv.gz,economic_lr,Economic left-right posterior mean,Posterior mean of economic left-right position,numeric,,0,1,,unit interval,0=left; 1=right,Posterior draws,Mean after inverse-logit transformation,
party_2d_election_year_panel_vN.csv.gz,galtan,Cultural posterior mean,Posterior mean of cultural position,numeric,,0,1,,unit interval,0=cosmopolitan/socially liberal; 1=traditionalist/nationalist,Posterior draws,Mean after inverse-logit transformation, party_2d_election_year_panel_vN.csv.gz,galtan,Cultural cosmopolitan--traditionalist posterior mean,Posterior mean of cultural cosmopolitan--traditionalist position,numeric,,0,1,,unit interval,0=cosmopolitan; 1=traditionalist,Posterior draws,Mean after inverse-logit transformation,
party_2d_election_year_panel_vN.csv.gz,economic_lr_se,Economic posterior standard error,Posterior standard deviation for economic_lr,numeric,,0,,,unit interval,,Posterior draws,Standard deviation over posterior draws, party_2d_election_year_panel_vN.csv.gz,economic_lr_se,Economic posterior standard error,Posterior standard deviation for economic_lr,numeric,,0,,,unit interval,,Posterior draws,Standard deviation over posterior draws,
party_2d_election_year_panel_vN.csv.gz,galtan_se,Cultural posterior standard error,Posterior standard deviation for galtan,numeric,,0,,,unit interval,,Posterior draws,Standard deviation over posterior draws, party_2d_election_year_panel_vN.csv.gz,galtan_se,Cultural posterior standard error,Posterior standard deviation for the cultural estimate,numeric,,0,,,unit interval,,Posterior draws,Standard deviation over posterior draws,
party_2d_election_year_panel_vN.csv.gz,economic_lr_q025,Economic lower posterior interval,2.5 percent posterior quantile for economic_lr,numeric,,0,1,,unit interval,0=left; 1=right,Posterior draws,Quantile over posterior draws, party_2d_election_year_panel_vN.csv.gz,economic_lr_q025,Economic lower posterior interval,2.5 percent posterior quantile for economic_lr,numeric,,0,1,,unit interval,0=left; 1=right,Posterior draws,Quantile over posterior draws,
party_2d_election_year_panel_vN.csv.gz,economic_lr_q975,Economic upper posterior interval,97.5 percent posterior quantile for economic_lr,numeric,,0,1,,unit interval,0=left; 1=right,Posterior draws,Quantile over posterior draws, party_2d_election_year_panel_vN.csv.gz,economic_lr_q975,Economic upper posterior interval,97.5 percent posterior quantile for economic_lr,numeric,,0,1,,unit interval,0=left; 1=right,Posterior draws,Quantile over posterior draws,
party_2d_election_year_panel_vN.csv.gz,galtan_q025,Cultural lower posterior interval,2.5 percent posterior quantile for galtan,numeric,,0,1,,unit interval,0=cosmopolitan/socially liberal; 1=traditionalist/nationalist,Posterior draws,Quantile over posterior draws, party_2d_election_year_panel_vN.csv.gz,galtan_q025,Cultural lower posterior interval,2.5 percent posterior quantile for the cultural estimate,numeric,,0,1,,unit interval,0=cosmopolitan; 1=traditionalist,Posterior draws,Quantile over posterior draws,
party_2d_election_year_panel_vN.csv.gz,galtan_q975,Cultural upper posterior interval,97.5 percent posterior quantile for galtan,numeric,,0,1,,unit interval,0=cosmopolitan/socially liberal; 1=traditionalist/nationalist,Posterior draws,Quantile over posterior draws, party_2d_election_year_panel_vN.csv.gz,galtan_q975,Cultural upper posterior interval,97.5 percent posterior quantile for the cultural estimate,numeric,,0,1,,unit interval,0=cosmopolitan; 1=traditionalist,Posterior draws,Quantile over posterior draws,
party_2d_election_year_panel_vN.csv.gz,election_id,Election identifier,Election identifier where available,string,,,,,identifier,,Election metadata,,Missing where no election identifier is available party_2d_election_year_panel_vN.csv.gz,election_id,Election identifier,Election identifier where available,string,,,,,identifier,,Election metadata,,Missing where no election identifier is available
party_2d_election_year_panel_vN.csv.gz,election_date,Election date,Election date where available,date,,,,,date,,Election metadata,,Missing in current processed election metadata party_2d_election_year_panel_vN.csv.gz,election_date,Election date,Election date where available,date,,,,,date,,Election metadata,,Missing in current processed election metadata
party_2d_election_year_panel_vN.csv.gz,has_text,Text support indicator,Indicator for direct or nearby text evidence,boolean,0;1,0,1,,indicator,,Source-support construction,Nearby threshold documented in source_support_dictionary.csv, party_2d_election_year_panel_vN.csv.gz,has_text,Text support indicator,Indicator for direct or nearby text evidence,boolean,0;1,0,1,,indicator,,Source-support construction,Nearby threshold documented in source_support_dictionary.csv,
1 file_name variable_name label description type allowed_values range_min range_max missing_value_code unit scale_direction constructed_from construction_rule notes
9 party_2d_election_year_panel_vN.csv.gz in_union Union membership indicator Indicator that the row is associated with a union or alliance boolean 0;1 0 1 indicator Alliance mapping
10 party_2d_election_year_panel_vN.csv.gz pervote Vote share Vote share at the election year numeric 0 100 percent Election metadata
11 party_2d_election_year_panel_vN.csv.gz economic_lr Economic left-right posterior mean Posterior mean of economic left-right position numeric 0 1 unit interval 0=left; 1=right Posterior draws Mean after inverse-logit transformation
12 party_2d_election_year_panel_vN.csv.gz galtan Cultural posterior mean Cultural cosmopolitan--traditionalist posterior mean Posterior mean of cultural position Posterior mean of cultural cosmopolitan--traditionalist position numeric 0 1 unit interval 0=cosmopolitan/socially liberal; 1=traditionalist/nationalist 0=cosmopolitan; 1=traditionalist Posterior draws Mean after inverse-logit transformation
13 party_2d_election_year_panel_vN.csv.gz economic_lr_se Economic posterior standard error Posterior standard deviation for economic_lr numeric 0 unit interval Posterior draws Standard deviation over posterior draws
14 party_2d_election_year_panel_vN.csv.gz galtan_se Cultural posterior standard error Posterior standard deviation for galtan Posterior standard deviation for the cultural estimate numeric 0 unit interval Posterior draws Standard deviation over posterior draws
15 party_2d_election_year_panel_vN.csv.gz economic_lr_q025 Economic lower posterior interval 2.5 percent posterior quantile for economic_lr numeric 0 1 unit interval 0=left; 1=right Posterior draws Quantile over posterior draws
16 party_2d_election_year_panel_vN.csv.gz economic_lr_q975 Economic upper posterior interval 97.5 percent posterior quantile for economic_lr numeric 0 1 unit interval 0=left; 1=right Posterior draws Quantile over posterior draws
17 party_2d_election_year_panel_vN.csv.gz galtan_q025 Cultural lower posterior interval 2.5 percent posterior quantile for galtan 2.5 percent posterior quantile for the cultural estimate numeric 0 1 unit interval 0=cosmopolitan/socially liberal; 1=traditionalist/nationalist 0=cosmopolitan; 1=traditionalist Posterior draws Quantile over posterior draws
18 party_2d_election_year_panel_vN.csv.gz galtan_q975 Cultural upper posterior interval 97.5 percent posterior quantile for galtan 97.5 percent posterior quantile for the cultural estimate numeric 0 1 unit interval 0=cosmopolitan/socially liberal; 1=traditionalist/nationalist 0=cosmopolitan; 1=traditionalist Posterior draws Quantile over posterior draws
19 party_2d_election_year_panel_vN.csv.gz election_id Election identifier Election identifier where available string identifier Election metadata Missing where no election identifier is available
20 party_2d_election_year_panel_vN.csv.gz election_date Election date Election date where available date date Election metadata Missing in current processed election metadata
21 party_2d_election_year_panel_vN.csv.gz has_text Text support indicator Indicator for direct or nearby text evidence boolean 0;1 0 1 indicator Source-support construction Nearby threshold documented in source_support_dictionary.csv
+3 -3
View File
@@ -5,7 +5,7 @@
## Executes the complete pipeline: data loading → preparation → model fitting ## Executes the complete pipeline: data loading → preparation → model fitting
## ##
## Supports two model versions: ## Supports two model versions:
## - "2dim": 2D bipolar model (V1) - estimates economic_lr and galtan directly ## - "2dim": 2D bipolar model (V1) - estimates economic left-right and cultural cosmopolitan--traditionalist positions directly
## - "4dim": 4D unipolar model (V10) - estimates 4 traits, derives 2 scales ## - "4dim": 4D unipolar model (V10) - estimates 4 traits, derives 2 scales
## ##
## Default is 2D model (better identification, faster convergence) ## Default is 2D model (better identification, faster convergence)
@@ -40,7 +40,7 @@ println(" Adapt delta: $(ADAPT_DELTA)")
println(" Max depth: $(MAX_DEPTH)") println(" Max depth: $(MAX_DEPTH)")
println(" Start year: $(START_YEAR)") println(" Start year: $(START_YEAR)")
if MODEL_VERSION == "2dim" if MODEL_VERSION == "2dim"
println("\n 2D MODEL: Estimates economic_lr and galtan directly") println("\n 2D MODEL: Estimates economic left-right and cultural cosmopolitan--traditionalist positions directly")
println(" (Half the parameters, better convergence)") println(" (Half the parameters, better convergence)")
else else
println("\n 4D MODEL: Estimates 4 traits, derives 2 scales") println("\n 4D MODEL: Estimates 4 traits, derives 2 scales")
@@ -256,7 +256,7 @@ function run_model(;
println(" Expert dimension-specific observations: $(dat_4dim["N_exp_dim"])") println(" Expert dimension-specific observations: $(dat_4dim["N_exp_dim"])")
println(" Expert general L-R observations: $(dat_4dim["N_exp_lr"])") println(" Expert general L-R observations: $(dat_4dim["N_exp_lr"])")
if MODEL_VERSION == "2dim" if MODEL_VERSION == "2dim"
println(" Dimensions estimated: 2 (economic_lr, galtan)") println(" Dimensions estimated: 2 (economic left-right, cultural cosmopolitan--traditionalist)")
println(" Theta parameters: $(2 * data_prep.R) (2 × R)") println(" Theta parameters: $(2 * data_prep.R) (2 × R)")
else else
println(" Dimensions estimated: 4 (pro_market, pro_welfare, cosmopolitan, traditional)") println(" Dimensions estimated: 4 (pro_market, pro_welfare, cosmopolitan, traditional)")
+9 -9
View File
@@ -3,7 +3,7 @@
02_post_estimation.jl - Extract party position estimates from Stan model output 02_post_estimation.jl - Extract party position estimates from Stan model output
Supports both model versions: Supports both model versions:
- 2D model (V1): Extracts economic_lr and galtan directly - 2D model (V1): Extracts economic left-right and cultural cosmopolitan--traditionalist positions directly
- 4D model (V10): Extracts 4 traits + 2 derived scales - 4D model (V10): Extracts 4 traits + 2 derived scales
V10/V1 UPDATE: Handles segment-based indexing V10/V1 UPDATE: Handles segment-based indexing
@@ -520,7 +520,7 @@ function extract_estimates(chains::DataFrame, segment_year_map::DataFrame, R::In
# Select quantities based on model version # Select quantities based on model version
if model_version == "2dim" if model_version == "2dim"
# 2D model: economic_lr and galtan are directly estimated # 2D model: economic left-right and cultural cosmopolitan--traditionalist positions are directly estimated
# (general_lr is computed in Stan for anchoring but not extracted as output) # (general_lr is computed in Stan for anchoring but not extracted as output)
quantities = ["economic_lr", "galtan"] quantities = ["economic_lr", "galtan"]
test_col = "economic_lr.1" test_col = "economic_lr.1"
@@ -703,7 +703,7 @@ function validate_output(output::DataFrame, segment_info::Union{DataFrame, Nothi
econ_marker = econ_ok ? "" : "*" econ_marker = econ_ok ? "" : "*"
galtan_marker = galtan_ok ? "" : "*" galtan_marker = galtan_ok ? "" : "*"
@printf(" %-15s econ=%.2f%s [%.2f-%.2f] galtan=%.2f%s [%.2f-%.2f] %s\n", @printf(" %-15s economic=%.2f%s [%.2f-%.2f] cultural=%.2f%s [%.2f-%.2f] %s\n",
anchor.name, mean_econ, econ_marker, anchor.econ[1], anchor.econ[2], anchor.name, mean_econ, econ_marker, anchor.econ[1], anchor.econ[2],
mean_galtan, galtan_marker, anchor.galtan[1], anchor.galtan[2], status) mean_galtan, galtan_marker, anchor.galtan[1], anchor.galtan[2], status)
end end
@@ -845,9 +845,9 @@ function save_output(output::DataFrame, metadata::Dict, segment_info::Union{Data
if is_2d if is_2d
println(f, "Model: 2D Direct Bipolar") println(f, "Model: 2D Direct Bipolar")
println(f, "") println(f, "")
println(f, "Bipolar scales (0 = left/GAL, 1 = right/TAN):") println(f, "Bipolar scales (0 = left/cosmopolitan, 1 = right/traditionalist):")
println(f, " economic_lr: Economic left-right position (directly estimated)") println(f, " economic_lr: Economic left-right position (directly estimated)")
println(f, " galtan: GAL-TAN cultural position (directly estimated)") println(f, " galtan: Cultural cosmopolitan--traditionalist position (directly estimated)")
# Note: general_lr is computed internally for cross-dimensional anchoring # Note: general_lr is computed internally for cross-dimensional anchoring
# but not reported as output (the two dimension-specific estimates are preferred) # but not reported as output (the two dimension-specific estimates are preferred)
else else
@@ -856,12 +856,12 @@ function save_output(output::DataFrame, metadata::Dict, segment_info::Union{Data
println(f, "Dimensions (0 = low, 1 = high):") println(f, "Dimensions (0 = low, 1 = high):")
println(f, " pro_market: Pro-market economic position") println(f, " pro_market: Pro-market economic position")
println(f, " pro_welfare: Pro-welfare state position") println(f, " pro_welfare: Pro-welfare state position")
println(f, " cosmopolitan: Cosmopolitan/GAL cultural position") println(f, " cosmopolitan: Cosmopolitan cultural position")
println(f, " traditional: Traditional/TAN cultural position") println(f, " traditional: Traditionalist cultural position")
println(f, "") println(f, "")
println(f, "Derived bipolar scales (0 = left/GAL, 1 = right/TAN):") println(f, "Derived bipolar scales (0 = left/cosmopolitan, 1 = right/traditionalist):")
println(f, " economic_lr: Economic left-right (derived from pro_market - pro_welfare)") println(f, " economic_lr: Economic left-right (derived from pro_market - pro_welfare)")
println(f, " galtan: GAL-TAN (derived from traditional - cosmopolitan)") println(f, " galtan: Cultural cosmopolitan--traditionalist (derived from traditional - cosmopolitan)")
end end
println(f, "") println(f, "")
println(f, "Uncertainty columns:") println(f, "Uncertainty columns:")
+3 -3
View File
@@ -324,7 +324,7 @@ function validate_country_patterns(model::DataFrame)
sort!(country_stats, :n_obs, rev=true) sort!(country_stats, :n_obs, rev=true)
@printf("%-4s %6s %6s %8s %8s %8s %8s\n", @printf("%-4s %6s %6s %8s %8s %8s %8s\n",
"CC", "Parties", "N", "Econ", "SD", "Galtan", "SD") "CC", "Parties", "N", "Econ", "SD", "Cult", "SD")
println("-"^60) println("-"^60)
for row in eachrow(country_stats[1:min(20, nrow(country_stats)), :]) for row in eachrow(country_stats[1:min(20, nrow(country_stats)), :])
@@ -349,9 +349,9 @@ function validate_country_patterns(model::DataFrame)
push!(issues, "right-skewed economy") push!(issues, "right-skewed economy")
end end
if row.mean_galtan < 0.35 if row.mean_galtan < 0.35
push!(issues, "cultural-skewed") push!(issues, "cosmopolitan-skewed")
elseif row.mean_galtan > 0.65 elseif row.mean_galtan > 0.65
push!(issues, "TAN-skewed") push!(issues, "traditionalist-skewed")
end end
println(" $(row.country): $(join(issues, ", "))") println(" $(row.country): $(join(issues, ", "))")
end end
+11 -11
View File
@@ -201,13 +201,13 @@ function validate_economic_lr(model::DataFrame, expert::DataFrame)
end end
function validate_galtan(model::DataFrame, expert::DataFrame) function validate_galtan(model::DataFrame, expert::DataFrame)
"""Validate galtan against CHES galtan and V-Party/GPS libcons""" """Validate cultural cosmopolitan--traditionalist estimates against CHES and V-Party/GPS cultural measures"""
println("\n" * "="^60) println("\n" * "="^60)
println("CONVERGENT VALIDITY: galtan") println("CONVERGENT VALIDITY: cultural cosmopolitan--traditionalist")
println("="^60) println("="^60)
# Filter expert data for GAL-TAN dimension # Filter expert data for cultural cosmopolitan--traditionalist dimension
galtan_vars = filter(v -> occursin("galtan", v) || occursin("libcon", v), unique(expert.var)) galtan_vars = filter(v -> occursin("galtan", v) || occursin("libcon", v), unique(expert.var))
galtan_expert = filter(row -> row.var in galtan_vars, expert) galtan_expert = filter(row -> row.var in galtan_vars, expert)
@@ -338,17 +338,17 @@ function validate_discriminant(model::DataFrame, expert::DataFrame)
@printf(" Model Economic × Expert Economic: r = %.3f (convergent, n=%d)\n", r, nrow(merged_ee)) @printf(" Model Economic × Expert Economic: r = %.3f (convergent, n=%d)\n", r, nrow(merged_ee))
end end
# 2. Expert economic vs Model galtan (discriminant) # 2. Expert economic vs model cultural dimension (discriminant)
merged_eg = innerjoin(econ_expert, model_gal, on=[:party, :year]) merged_eg = innerjoin(econ_expert, model_gal, on=[:party, :year])
if nrow(merged_eg) >= 10 if nrow(merged_eg) >= 10
r = cor(merged_eg.val, merged_eg.galtan) r = cor(merged_eg.val, merged_eg.galtan)
push!(results, (model_dim="galtan", expert_dim="economic", push!(results, (model_dim="galtan", expert_dim="economic",
r_pearson=r, r_spearman=corspearman(merged_eg.val, merged_eg.galtan), r_pearson=r, r_spearman=corspearman(merged_eg.val, merged_eg.galtan),
n=nrow(merged_eg), type="discriminant")) n=nrow(merged_eg), type="discriminant"))
@printf(" Model GAL-TAN × Expert Economic: r = %.3f (discriminant, n=%d)\n", r, nrow(merged_eg)) @printf(" Model Cultural × Expert Economic: r = %.3f (discriminant, n=%d)\n", r, nrow(merged_eg))
end end
# 3. Expert galtan vs Model galtan (convergent - already computed, include for matrix) # 3. Expert cultural vs model cultural dimension (convergent - already computed, include for matrix)
galtan_vars = filter(v -> occursin("galtan", v) || occursin("libcon", v), unique(expert.var)) galtan_vars = filter(v -> occursin("galtan", v) || occursin("libcon", v), unique(expert.var))
galtan_expert = filter(row -> row.var in galtan_vars, expert) galtan_expert = filter(row -> row.var in galtan_vars, expert)
merged_gg = innerjoin(galtan_expert, model_gal, on=[:party, :year]) merged_gg = innerjoin(galtan_expert, model_gal, on=[:party, :year])
@@ -357,22 +357,22 @@ function validate_discriminant(model::DataFrame, expert::DataFrame)
push!(results, (model_dim="galtan", expert_dim="galtan", push!(results, (model_dim="galtan", expert_dim="galtan",
r_pearson=r, r_spearman=corspearman(merged_gg.val, merged_gg.galtan), r_pearson=r, r_spearman=corspearman(merged_gg.val, merged_gg.galtan),
n=nrow(merged_gg), type="convergent")) n=nrow(merged_gg), type="convergent"))
@printf(" Model GAL-TAN × Expert GAL-TAN: r = %.3f (convergent, n=%d)\n", r, nrow(merged_gg)) @printf(" Model Cultural × Expert Cultural: r = %.3f (convergent, n=%d)\n", r, nrow(merged_gg))
end end
# 4. Expert galtan vs Model economic (discriminant) # 4. Expert cultural vs model economic dimension (discriminant)
merged_ge = innerjoin(galtan_expert, model_econ, on=[:party, :year]) merged_ge = innerjoin(galtan_expert, model_econ, on=[:party, :year])
if nrow(merged_ge) >= 10 if nrow(merged_ge) >= 10
r = cor(merged_ge.val, merged_ge.economic_lr) r = cor(merged_ge.val, merged_ge.economic_lr)
push!(results, (model_dim="economic_lr", expert_dim="galtan", push!(results, (model_dim="economic_lr", expert_dim="galtan",
r_pearson=r, r_spearman=corspearman(merged_ge.val, merged_ge.economic_lr), r_pearson=r, r_spearman=corspearman(merged_ge.val, merged_ge.economic_lr),
n=nrow(merged_ge), type="discriminant")) n=nrow(merged_ge), type="discriminant"))
@printf(" Model Economic × Expert GAL-TAN: r = %.3f (discriminant, n=%d)\n", r, nrow(merged_ge)) @printf(" Model Economic × Expert Cultural: r = %.3f (discriminant, n=%d)\n", r, nrow(merged_ge))
end end
println() println()
println("MTMM Matrix:") println("MTMM Matrix:")
println(" Expert Economic Expert GAL-TAN") println(" Expert Economic Expert Cultural")
for r in results for r in results
if r.model_dim == "economic_lr" && r.expert_dim == "economic" if r.model_dim == "economic_lr" && r.expert_dim == "economic"
@printf(" Model Economic: %.3f ", r.r_pearson) @printf(" Model Economic: %.3f ", r.r_pearson)
@@ -385,7 +385,7 @@ function validate_discriminant(model::DataFrame, expert::DataFrame)
end end
for r in results for r in results
if r.model_dim == "galtan" && r.expert_dim == "economic" if r.model_dim == "galtan" && r.expert_dim == "economic"
@printf(" Model GAL-TAN: %.3f ", r.r_pearson) @printf(" Model Cultural: %.3f ", r.r_pearson)
end end
end end
for r in results for r in results
+4 -3
View File
@@ -87,7 +87,7 @@ function load_chains_selective(run_dir::String, needed_rr::Set{Int}, K::Int)
# Build the set of column names we need # Build the set of column names we need
needed_cols = Set{String}() needed_cols = Set{String}()
# theta columns: economic_lr.{rr} and galtan.{rr} for each unique rr # theta columns: economic_lr.{rr} and galtan.{rr} (cultural cosmopolitan--traditionalist) for each unique rr
for rr in needed_rr for rr in needed_rr
push!(needed_cols, "economic_lr.$rr") push!(needed_cols, "economic_lr.$rr")
push!(needed_cols, "galtan.$rr") push!(needed_cols, "galtan.$rr")
@@ -384,6 +384,7 @@ function summarize_coverage(result::DataFrame, ci_level::Float64)
# Overall by dimension # Overall by dimension
dim_names = Dict(1 => "economic_lr", 2 => "galtan") dim_names = Dict(1 => "economic_lr", 2 => "galtan")
display_dim_names = Dict(1 => "economic left-right", 2 => "cultural cosmopolitan--traditionalist")
summary_rows = [] summary_rows = []
for dim in sort(unique(result.dim_idx)) for dim in sort(unique(result.dim_idx))
@@ -394,8 +395,8 @@ function summarize_coverage(result::DataFrame, ci_level::Float64)
ci = wilson_ci(ppc, n) ci = wilson_ci(ppc, n)
dim_name = dim_names[dim] dim_name = dim_names[dim]
println(@sprintf("\n %-15s: %.1f%% [%.1f%%, %.1f%%] (%d/%d)", println(@sprintf("\n %-40s: %.1f%% [%.1f%%, %.1f%%] (%d/%d)",
dim_name, 100*ppc, 100*ci.lower, 100*ci.upper, n_covered, n)) display_dim_names[dim], 100*ppc, 100*ci.lower, 100*ci.upper, n_covered, n))
push!(summary_rows, ( push!(summary_rows, (
dimension = dim_name, dimension = dim_name,