Analyze Your Conjoint Data
analyze.Rmd
🎯 Estimate Corrected MMs or AMCEs
In conjoint analysis, default MMs and AMCEs can be biased due to measurement error from intra-respondent variability.
projoint corrects for this bias automatically.
📦 Prepare Example Data
outcomes <- paste0("choice", 1:8)
outcomes <- c(outcomes, "choice1_repeated_flipped")
out1 <- reshape_projoint(exampleData1, outcomes)
🛠️ Why Use IDs (e.g., att1
, level1
)?
Before estimating quantities, it’s important to understand how attribute and level IDs work inside projoint.
We recommend working with attribute IDs rather than actual text labels because:
- Safer against special characters, languages, or typos
- Allows multiple attributes to have identical labels (e.g., “High” for both “Teaching Quality” and “Research Quality”)
Check attribute-level mappings:
out1$labels
## # A tibble: 24 × 4
## attribute level attribute_id level_id
## <chr> <chr> <chr> <chr>
## 1 Housing Cost 15% of pre-tax income att1 att1:leve…
## 2 Housing Cost 30% of pre-tax income att1 att1:leve…
## 3 Housing Cost 40% of pre-tax income att1 att1:leve…
## 4 Presidential Vote (2020) 30% Democrat, 70% Republican att2 att2:leve…
## 5 Presidential Vote (2020) 50% Democrat, 50% Republican att2 att2:leve…
## 6 Presidential Vote (2020) 70% Democrat, 30% Republican att2 att2:leve…
## 7 Racial Composition 50% White, 50% Nonwhite att3 att3:leve…
## 8 Racial Composition 75% White, 25% Nonwhite att3 att3:leve…
## 9 Racial Composition 90% White, 10% Nonwhite att3 att3:leve…
## 10 Racial Composition 96% White, 4% Nonwhite att3 att3:leve…
## # ℹ 14 more rows
You can also save these labels for easier editing:
save_labels(out1, "labels.csv")
📈 Estimate Marginal Means (MMs)
Choice-Level MMs (Specific Level)
qoi_2 <- set_qoi(
.structure = "choice_level",
.att_choose = "att1",
.lev_choose = "level3",
.att_notchoose = "att1",
.lev_notchoose = "level1"
)
mm2 <- projoint(out1, .qoi = qoi_2, .ignore_position = FALSE)
print(mm2)
##
## Projoint results object
## -------------------------
## Estimand: mm
## Structure: choice_level
## Standard error method: analytical
## IRR: Estimated
## Tau: 0.172
## Number of estimates: 2
summary(mm2)
##
## Summary of Projoint Estimates
## ------------------------------
## Estimand: mm
## Structure: choice_level
## Standard error method: analytical
## IRR: Estimated
## Tau: 0.172
## # A tibble: 2 × 7
## estimand estimate se conf.low conf.high att_level_choose
## <chr> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 mm_uncorrected 0.402 0.0258 0.352 0.453 att1:level3
## 2 mm_corrected 0.351 0.0408 0.271 0.431 att1:level3
## # ℹ 1 more variable: att_level_notchoose <chr>
Profile-Level MMs (All Levels)
##
## Projoint results object
## -------------------------
## Estimand: mm
## Structure: profile_level
## Standard error method: analytical
## IRR: Estimated
## Tau: 0.172
## Number of estimates: 48
summary(mm0)
##
## Summary of Projoint Estimates
## ------------------------------
## Estimand: mm
## Structure: profile_level
## Standard error method: analytical
## IRR: Estimated
## Tau: 0.172
## # A tibble: 48 × 6
## estimand estimate se conf.low conf.high att_level_choose
## <chr> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 mm_uncorrected 0.574 0.0134 0.548 0.601 att1:level1
## 2 mm_corrected 0.614 0.0207 0.573 0.654 att1:level1
## 3 mm_uncorrected 0.485 0.0134 0.458 0.511 att1:level2
## 4 mm_corrected 0.477 0.0204 0.437 0.517 att1:level2
## 5 mm_uncorrected 0.445 0.0131 0.419 0.470 att1:level3
## 6 mm_corrected 0.416 0.0203 0.376 0.455 att1:level3
## 7 mm_uncorrected 0.489 0.0133 0.463 0.515 att2:level1
## 8 mm_corrected 0.483 0.0202 0.443 0.522 att2:level1
## 9 mm_uncorrected 0.524 0.0130 0.498 0.549 att2:level2
## 10 mm_corrected 0.536 0.0200 0.497 0.575 att2:level2
## # ℹ 38 more rows
Profile-Level MMs (Specific Level)
qoi_1 <- set_qoi(
.structure = "profile_level",
.estimand = "mm",
.att_choose = "att1",
.lev_choose = "level1"
)
mm1 <- projoint(out1, .qoi = qoi_1)
print(mm1)
##
## Projoint results object
## -------------------------
## Estimand: mm
## Structure: profile_level
## Standard error method: analytical
## IRR: Estimated
## Tau: 0.172
## Number of estimates: 2
summary(mm1)
##
## Summary of Projoint Estimates
## ------------------------------
## Estimand: mm
## Structure: profile_level
## Standard error method: analytical
## IRR: Estimated
## Tau: 0.172
## # A tibble: 2 × 7
## estimand estimate se conf.low conf.high att_level_choose
## <chr> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 mm_uncorrected 0.574 0.0134 0.548 0.601 att1:level1
## 2 mm_corrected 0.614 0.0207 0.573 0.654 att1:level1
## # ℹ 1 more variable: att_level_notchoose <chr>
Profile-Level MMs (Specific Level, Manual IRR)
##
## Projoint results object
## -------------------------
## Estimand: mm
## Structure: profile_level
## Standard error method: analytical
## IRR: Assumed (0.75)
## Tau: 0.146
## Number of estimates: 2
summary(mm1b)
##
## Summary of Projoint Estimates
## ------------------------------
## Estimand: mm
## Structure: profile_level
## Standard error method: analytical
## IRR: Assumed (0.75)
## Tau: 0.146
## # A tibble: 2 × 7
## estimand estimate se conf.low conf.high att_level_choose
## <chr> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 mm_uncorrected 0.574 0.0134 0.548 0.601 att1:level1
## 2 mm_corrected 0.605 0.0190 0.568 0.643 att1:level1
## # ℹ 1 more variable: att_level_notchoose <chr>
📉 Estimate AMCEs
Choice-Level AMCEs (Specific Level)
qoi_4 <- set_qoi(
.structure = "choice_level",
.estimand = "amce",
.att_choose = "att1",
.lev_choose = "level3",
.att_notchoose = "att1",
.lev_notchoose = "level1",
.att_choose_b = "att1",
.lev_choose_b = "level2",
.att_notchoose_b = "att1",
.lev_notchoose_b = "level1"
)
amce2 <- projoint(out1, .qoi = qoi_4, .ignore_position = TRUE)
print(amce2)
##
## Projoint results object
## -------------------------
## Estimand: amce
## Structure: choice_level
## Standard error method: analytical
## IRR: Estimated
## Tau: 0.172
## Number of estimates: 2
summary(amce2)
##
## Summary of Projoint Estimates
## ------------------------------
## Estimand: amce
## Structure: choice_level
## Standard error method: analytical
## IRR: Estimated
## Tau: 0.172
## # A tibble: 2 × 9
## estimand estimate se conf.low conf.high att_level_choose
## <chr> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 amce_uncorrected -0.0484 0.0270 -0.101 0.00448 att1:level3
## 2 amce_corrected -0.0739 0.0414 -0.155 0.00727 att1:level3
## # ℹ 3 more variables: att_level_notchoose <chr>,
## # att_level_choose_baseline <chr>, att_level_notchoose_baseline <chr>
Profile-Level AMCEs (All Levels)
##
## Projoint results object
## -------------------------
## Estimand: amce
## Structure: profile_level
## Standard error method: analytical
## IRR: Estimated
## Tau: 0.172
## Number of estimates: 34
summary(amce0)
##
## Summary of Projoint Estimates
## ------------------------------
## Estimand: amce
## Structure: profile_level
## Standard error method: analytical
## IRR: Estimated
## Tau: 0.172
## # A tibble: 34 × 7
## estimand estimate se conf.low conf.high att_level_choose
## <chr> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 amce_uncorrected -0.0899 0.0190 -0.127 -0.0527 att1:level2
## 2 amce_corrected -0.137 0.0290 -0.194 -0.0801 att1:level2
## 3 amce_uncorrected -0.130 0.0188 -0.167 -0.0931 att1:level3
## 4 amce_corrected -0.198 0.0294 -0.256 -0.140 att1:level3
## 5 amce_uncorrected 0.0348 0.0186 -0.00170 0.0713 att2:level2
## 6 amce_corrected 0.0530 0.0284 -0.00258 0.109 att2:level2
## 7 amce_uncorrected -0.00177 0.0188 -0.0386 0.0350 att2:level3
## 8 amce_corrected -0.00270 0.0286 -0.0589 0.0535 att2:level3
## 9 amce_uncorrected 0.0240 0.0204 -0.0159 0.0640 att3:level2
## 10 amce_corrected 0.0366 0.0312 -0.0246 0.0979 att3:level2
## # ℹ 24 more rows
## # ℹ 1 more variable: att_level_choose_baseline <chr>
Profile-Level AMCEs (Specific Level)
qoi_3 <- set_qoi(
.structure = "profile_level",
.estimand = "amce",
.att_choose = "att1",
.lev_choose = "level3",
.att_choose_b = "att1",
.lev_choose_b = "level1"
)
amce1 <- projoint(out1, .qoi = qoi_3)
print(amce1)
##
## Projoint results object
## -------------------------
## Estimand: amce
## Structure: profile_level
## Standard error method: analytical
## IRR: Estimated
## Tau: 0.172
## Number of estimates: 2
summary(amce1)
##
## Summary of Projoint Estimates
## ------------------------------
## Estimand: amce
## Structure: profile_level
## Standard error method: analytical
## IRR: Estimated
## Tau: 0.172
## # A tibble: 2 × 9
## estimand estimate se conf.low conf.high att_level_choose
## <chr> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 amce_uncorrected -0.130 0.0188 -0.167 -0.0931 att1:level3
## 2 amce_corrected -0.198 0.0294 -0.256 -0.140 att1:level3
## # ℹ 3 more variables: att_level_notchoose <chr>,
## # att_level_choose_baseline <chr>, att_level_notchoose_baseline <chr>
Profile-Level AMCEs (Specific Level, Manual IRR)
##
## Projoint results object
## -------------------------
## Estimand: amce
## Structure: profile_level
## Standard error method: analytical
## IRR: Assumed (0.75)
## Tau: 0.146
## Number of estimates: 2
summary(amce1b)
##
## Summary of Projoint Estimates
## ------------------------------
## Estimand: amce
## Structure: profile_level
## Standard error method: analytical
## IRR: Assumed (0.75)
## Tau: 0.146
## # A tibble: 2 × 9
## estimand estimate se conf.low conf.high att_level_choose
## <chr> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 amce_uncorrected -0.130 0.0188 -0.167 -0.0931 att1:level3
## 2 amce_corrected -0.184 0.0266 -0.236 -0.132 att1:level3
## # ℹ 3 more variables: att_level_notchoose <chr>,
## # att_level_choose_baseline <chr>, att_level_notchoose_baseline <chr>
🔎 Predict Intra-Respondent Reliability (IRR)
If your design does not include a repeated task, you can predict IRR using predict_tau(), based on observed respondent behavior.
Predict IRR Using predict_tau()
data(out1_arranged)
predicted_irr <- predict_tau(out1_arranged)
print(predicted_irr)
## Tau estimated using the extrapolation method: 0.743
summary(predicted_irr)
## # A tibble: 8 × 2
## x predicted
## <int> <dbl>
## 1 0 0.743
## 2 1 0.709
## 3 2 0.675
## 4 3 0.640
## 5 4 0.606
## 6 5 0.572
## 7 6 0.537
## 8 7 0.503
plot(predicted_irr)
💡 Tip: When to Use .by_var
Use .by_var
only when comparing
profile-level MMs between two groups (e.g., Democrats
vs. Republicans).
For AMCEs or choice-level quantities, .by_var
is not
currently supported.
🌟 What’s Next?
Now that you have estimated key quantities, you’re ready to visualize your results clearly and effectively!
➡️ Continue to: Visualize
Your Results
⬅️ Back to: Wrangle Your
Data
🏠 Home: Home