Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Cramers V with weighted data

    Hello, I was wondering if anyone knew how to perform a Cramers V with weighted data? I found some code in this old Statalist post below. Would the code I produced based on the blog post below be an appropriate way to generate the weighted test statistic?

    Code:
      
    svy: tab biosex ai_mh, pearson
    
    local denom = min(e(r)-1, e(c)-1)
    
    display "Weighted Cramer's V = " ///
        sqrt(e(cun_Pear)/(e(N)*`denom'))

    https://www.stata.com/statalist/arch.../msg00581.html

    Last edited by Luis Mijares Castaneda; 08 Oct 2026, 16:25.

  • #2
    I was curious about this too, so I checked the formula and tried your code.
    It appears correct for estimating weighted Cramér’s V.
    Here, “uncorrected” means that e(cun_Pear) has not been adjusted for the survey design; it is still based on weighted proportions.
    For significance testing, use the design-based F test’s p-value, e(p_Pear), and report V as the effect size.

    Please double check the code below and anyone let me know if this works.

    Code:
    version 16.0
    clear all
    set more off
    
    * StataCorp. (2025). Stata 19 survey data reference manual. Stata Press.
    * [SVY] svy: tabulate twoway, Methods and formulas, The test statistics.
    * Entry PDF p. 24 (full manual printed p. 187):
    * https://www.stata.com/manuals/svysvytabulatetwoway.pdf#page=24
    *
    * X2_P = m * sum_r sum_c ((p_rc - p0_rc)^2 / p0_rc)
    * p0_rc = p_r+ * p_+c
    * m = unweighted number of observations in the analysis sample.
    * p_rc = weighted cell count / sum of weighted cell counts.
    * This computes uncorrected Pearson chi2, not the design-based F test.
    
    * 1. Artificial example: replace this section with your data and svyset.
    set obs 360
    generate long id = _n
    generate byte x = mod(id-1, 3) + 1
    generate byte y = mod(floor((id-1)/3), 3) + 1
    generate double weight = 0.7 + 2.3*(x==y) + 0.13*mod(id,7)
    generate int psu = ceil(id/6)
    generate byte stratum = ceil(psu/10)
    svyset psu [pweight=weight], strata(stratum)
    
    * 2. Stata benchmark; save results before changing the data.
    * For your data, replace x, y, and weight throughout the code.
    * Scope: ordinary pweights, without subpop(), tab(), standardization,
    * or poststratification/calibration that changes the effective weights.
    svy: tabulate x y, pearson
    scalar m = e(N)
    scalar X2_stata = e(cun_Pear)
    scalar k = min(e(r)-1, e(c)-1)
    scalar p_design = e(p_Pear)
    assert k > 0 & k < .
    
    * 3. Direct calculation from the individual-level weighted data.
    preserve
    keep if e(sample)
    keep x y weight
    
    * Nhat_rc: sum of sampling weights within each cell.
    collapse (sum) cell_w=weight, by(x y)
    
    * Include unobserved combinations as zero cells in the R x C table.
    fillin x y
    replace cell_w = 0 if _fillin
    drop _fillin
    
    * p_rc and its row/column marginals (manual pp. 22-23).
    egen double total_w = total(cell_w)
    generate double p_rc = cell_w/total_w
    bysort x: egen double p_row = total(p_rc)
    bysort y: egen double p_col = total(p_rc)
    
    * Null proportion under independence (manual p. 24).
    generate double p0_rc = p_row*p_col
    assert p0_rc > 0 & p0_rc < .
    
    * Pearson formula on p. 24, implemented term by term.
    generate double term = (p_rc-p0_rc)^2/p0_rc
    quietly summarize term, meanonly
    scalar X2_manual = m*r(sum)
    
    * Optional: derive weighted Cramer's V from the Pearson statistic.
    * This extra step is not itself a formula printed on manual p. 24.
    scalar V_weighted = sqrt(X2_manual/(m*k))
    
    sort x y
    format cell_w %12.4f
    format p_rc p_row p_col p0_rc term %10.6f
    list x y cell_w p_rc p_row p_col p0_rc term, noobs sepby(x)
    restore
    
    * 4. Numerical verification and results.
    assert reldif(X2_manual, X2_stata) < 1e-10
    display "m (sample size)       = " %12.0f m
    display "Pearson chi2 (manual) = " %12.8f X2_manual
    display "Pearson chi2 (Stata)  = " %12.8f X2_stata
    display "Weighted Cramer's V  = " %12.8f V_weighted
    display "Design-based p-value = " %12.5g p_design
    display "PASS: manual p. 24 formula agrees with e(cun_Pear)."

    Comment

    Working...
    X