easystats / easystats/effectsize

Discrepancy in `t_to_d`

Open
#212 18 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Discussion 🦜
Dominant language
R
Stars
353
Forks
25
Avg merge
9h 21m
Merged PRs (30d)
1

Description

Describe the bug
I was doing a comparison between the results of emmeans::eff_size() and effectsize::t_to_d(), and come up with very different results

To Reproduce

require(effectsize)
#> Loading required package: effectsize
require(emmeans)
#> Loading required package: emmeans

warp.lm = lm(breaks ~ tension, data = warpbreaks)
emm = emmeans(warp.lm, "tension")

### Using emmeans::eff_size
eff_size(emm, sigma = sigma(warp.lm), edf = df.residual(warp.lm))

#>  contrast effect.size    SE df lower.CL upper.CL
#>  L - M          0.842 0.344 51    0.152     1.53
#>  L - H          1.239 0.355 51    0.526     1.95
#>  M - H          0.397 0.336 51   -0.276     1.07
#> 
#> sigma used for effect sizes: 11.88 
#> Confidence level used: 0.95

### Using t_to_d
t = summary(pairs(emm)) $ t.ratio
t_to_d(t, df = df.residual(warp.lm))

#>    d |        95% CI
#> --------------------
#> 0.71 | [ 0.14, 1.27]
#> 1.04 | [ 0.45, 1.62]
#> 0.33 | [-0.22, 0.89]

Note that the estimated effect sizes are somewhat smaller than yielded by eff_size().

My own equivalent function
  • Since d = delta / sigma (where delta is the difference of means), and t = delta / (sigma * sqrt (2 / n)), we have that d = sqrt(2 / n) * t.
  • Meanwhile, df = k * (n - 1) where k is the number of groups, so that n = 1 + df / k.
  • Finally, to get k, the number of t ratios is k * (k - 1) / 2, so k = (1 + sqrt(1 + 8 * L)) / 2, where L is the number of t ratios.

Hence, my own version of t_to_d(), implementing these steps backwards:

### My own equivalent (just the point estimates)
rvl_t2d = function(t, df) {
    k = (1 + sqrt(1 + 8 * length(t))) / 2
    n = 1 + df / k
    sqrt(2 / n) * t
}

rvl_t2d(t, df.residual(warp.lm))

#> [1] 0.8417098 1.2391839 0.3974741

These results agree with the emmeans::eff_size() results.

Additional comment

My rvl_t2d() function depends on our having a balanced experiment with independent samples. Anyn such function that depends only on t ratios and df would require the same assumption (or something equally restrictive). The function emmeans::eff_size() does not require such a simplifying assumption, as it actually estimates each pairwise difference and divides it by the estimate of sigma. That's one reason I am quite sure that its results are correct. But I would think that effectsize::t_to_d() should yield the same results when those restrictive assumptions are satisfied, as they are in this illustration. I am not well-versed in the effect-size literature so I cannot comment with any authority on the formulas given in the documentation for t_to_d().

My system
R.Version()
#> $platform
#> [1] "x86_64-w64-mingw32"
#> 
#> $arch
#> [1] "x86_64"
#> 
#> $os
#> [1] "mingw32"
#> 
#> $system
#> [1] "x86_64, mingw32"
#> 
#> $status
#> [1] ""
#> 
#> $major
#> [1] "4"
#> 
#> $minor
#> [1] "0.3"
#> 
#> $year
#> [1] "2020"
#> 
#> $month
#> [1] "10"
#> 
#> $day
#> [1] "10"
#> 
#> $`svn rev`
#> [1] "79318"
#> 
#> $language
#> [1] "R"
#> 
#> $version.string
#> [1] "R version 4.0.3 (2020-10-10)"
#> 
#> $nickname
#> [1] "Bunny-Wunnies Freak Out"

packageVersion("effectsize")
#> [1] '0.4.0'

packageVersion("emmeans")
#> [1] '1.5.2.10003'

Created on 2020-11-28 by the reprex package (v0.3.0)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the t_to_d() entry point and run the supplied warpbreaks, emmeans, and effectsize reproduction. Compare its point estimates and confidence intervals with emmeans::eff_size() and the reported balanced-design calculation; done means the discrepancy is explained and the expected behavior is clearly established.

Written by the indexing model from the issue text.

Assessment

Tech stack
r
Domain
analytics
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.