Skip to content

Feature Request: Contrasting Simple Slopes#301

Merged
strengejacke merged 10 commits intomainfrom
strengejacke/issue238
Jan 9, 2025
Merged

Feature Request: Contrasting Simple Slopes#301
strengejacke merged 10 commits intomainfrom
strengejacke/issue238

Conversation

@strengejacke
Copy link
Member

Fixes #238

@DominiqueMakowski
Copy link
Member

API-wise I think it would make sense to add a estimate_contrasts() method to apply to estimate_slopes() outputs

estimate_slopes(m) |> estimate_contrasts()

Instead of complexifying the estimate_slopes() itself

@strengejacke strengejacke marked this pull request as ready for review January 9, 2025 09:28
@DominiqueMakowski
Copy link
Member

(although then the same could be said about having a working estimate_means(m) |> estimate_contrasts() workflow)

@strengejacke
Copy link
Member Author

It would be the same we do with estimate_means() and estimate_contrasts() for {marginaleffects}. You just need to add the hypothesis argument to the call marginaleffects::avg_predictions(). I think we should do the same for contrasts from slopes, that avoids duplicated code. This is passed via ..., so from a user perspective, no more complexity.

(we still can think about options to pipe...)

@DominiqueMakowski
Copy link
Member

Yes, we would still not recompute from scratch

I reckon a pipe workflow would just be syntactic sugar for:

estimate_contrasts.estimate_means <- function(x) {
  model <- extract_model(x)
  # recompute contrasts
  estimate_contrasts(model, ...)
}

@strengejacke
Copy link
Member Author

Seems to work in general...

library(modelbased)
fit <- lm(Sepal.Width ~ Petal.Length * Species, data = iris)

estimate_slopes(fit, trend = "Petal.Length", backend = "marginaleffects")
#> Estimated Marginal Effects
#> 
#> Parameter    | Coefficient |       95% CI | Predicted |      p
#> --------------------------------------------------------------
#> Petal.Length |        0.33 | [0.14, 0.52] |      3.40 | < .001
#> Marginal effects estimated for Petal.Length
emmeans::emtrends(fit, specs = ~Petal.Length, var = "Petal.Length")
#> NOTE: Results may be misleading due to involvement in interactions
#>  Petal.Length Petal.Length.trend     SE  df lower.CL upper.CL
#>          3.76              0.332 0.0964 144    0.142    0.523
#> 
#> Results are averaged over the levels of: Species 
#> Confidence level used: 0.95

estimate_slopes(fit, trend = "Petal.Length", by = "Species", backend = "marginaleffects")
#> Estimated Marginal Effects
#> 
#> Parameter    |    Species | Coefficient |        95% CI |      p
#> ----------------------------------------------------------------
#> Petal.Length |     setosa |        0.39 | [-0.12, 0.90] | 0.136 
#> Petal.Length | versicolor |        0.37 | [ 0.19, 0.56] | < .001
#> Petal.Length |  virginica |        0.23 | [ 0.07, 0.39] | 0.004 
#> Marginal effects estimated for Petal.Length

estimate_contrasts(fit, contrast = "Petal.Length", by = "Species", backend = "marginaleffects")
#> Marginal Contrasts Analysis
#> 
#> Parameter              | Coefficient |        95% CI |      p
#> -------------------------------------------------------------
#> setosa - versicolor    |        0.01 | [-0.53, 0.56] | > .999
#> setosa - virginica     |        0.15 | [-0.38, 0.69] | > .999
#> versicolor - virginica |        0.14 | [-0.11, 0.39] | 0.804 
#> 
#> Marginal contrasts estimated at Petal.Length
#> p-value adjustment method: Holm (1979)

emmeans::emtrends(fit, specs = pairwise ~ Species, var = "Petal.Length")
#> $emtrends
#>  Species    Petal.Length.trend     SE  df lower.CL upper.CL
#>  setosa                  0.388 0.2600 144  -0.1264    0.902
#>  versicolor              0.374 0.0961 144   0.1843    0.564
#>  virginica               0.234 0.0819 144   0.0725    0.396
#> 
#> Confidence level used: 0.95 
#> 
#> $contrasts
#>  contrast               estimate    SE  df t.ratio p.value
#>  setosa - versicolor      0.0136 0.277 144   0.049  0.9987
#>  setosa - virginica       0.1535 0.273 144   0.563  0.8400
#>  versicolor - virginica   0.1400 0.126 144   1.108  0.5105
#> 
#> P value adjustment: tukey method for comparing a family of 3 estimates

Created on 2025-01-09 with reprex v2.1.1

@strengejacke strengejacke merged commit 6ecbfb3 into main Jan 9, 2025
17 of 22 checks passed
@strengejacke strengejacke deleted the strengejacke/issue238 branch January 9, 2025 10:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: Contrasting Simple Slopes

2 participants