r-causal / tipr

An R package for conducting sensitivity analyses for unmeasured confounders
https://r-causal.github.io/tipr/
Other
33 stars 2 forks source link

make the default of `adjust_coef_with_binary()` adjust linear model coef #12

Closed malcolmbarrett closed 1 year ago

malcolmbarrett commented 2 years ago
library(tipr)
# IPW estimates without unmeasured confounder 
estimates <- c(estimate = -12.5, conf.low = -13.8, conf.high = -11.3)

adjust_coef_with_binary(
  estimates, 
  exposed_confounder_prev = 0.25, 
  unexposed_confounder_prev = .05, 
  confounder_outcome_effect = -8
)

#> # A tibble: 3 × 5
#>   effect_adjusted effect_observed exposed_confounder_prev unexposed_co…¹ confo…²
#>             <dbl>           <dbl>                   <dbl>          <dbl>   <dbl>
#> 1          -10.2            -12.5                    0.25           0.05      -8
#> 2          -11.5            -13.8                    0.25           0.05      -8
#> 3           -9.03           -11.3                    0.25           0.05      -8
#> # … with abbreviated variable names ¹​unexposed_confounder_prev,
#> #   ²​confounder_outcome_effect

Created on 2022-09-23 with reprex v2.0.2

LucyMcGowan commented 2 years ago

perfect! also make sure to add yourself to the description 🎉

malcolmbarrett commented 2 years ago

Added myself as contributor ✅

LucyMcGowan commented 2 years ago

@malcolmbarrett I rewent through the math this morning and realized it simplifies to basically the same equation as adjust_coef for the normally distributed case -- for linear regression it is just the difference in prevalences! This exercise actually led me down a rabbit hole that led me to looking this up in linear regression textbook which shows that we basically don't need any of our assumptions of independence of other confounders in the model (just additivity, so no interactions between unmeasured confounder and the outcome) and we can calculate the impact of the confounder using this:

image

I wonder if we should have totally separate functions for linear models since they are so much cleaner?

malcolmbarrett commented 2 years ago

Interesting. re: your first point, similar but not exactly the same as is. This is what you meant, yeah?

library(tipr)
# IPW estimates without unmeasured confounder 
estimates <- c(estimate = -12.5, conf.low = -13.8, conf.high = -11.3)

x <- adjust_coef_with_binary(
  unlist(estimates), 
  exposed_confounder_prev = 0.25, 
  unexposed_confounder_prev = .05, 
  confounder_outcome_effect = -8
)

y <- adjust_coef(
  unlist(estimates), 
  exposure_confounder_effect = 0.25 - .05, 
  confounder_outcome_effect = -8
)

tibble::tibble(x = x$effect_adjusted, y = y$effect_adjusted)
#> # A tibble: 3 × 2
#>        x     y
#>    <dbl> <dbl>
#> 1 -10.2  -10.9
#> 2 -11.5  -12.2
#> 3  -9.03  -9.7

Created on 2022-09-24 with reprex v2.0.2

LucyMcGowan commented 2 years ago

Yeah I had done something weird where I substituted part of the other equation where I shouldn’t have when deriving it, I’m pretty sure the effect of change in prevalence should just be linear because for linear regression that ends up being all that plays into the equation. I think because p0 was so tiny it looked the same in both cases in this particular example but it could look different for other values if that makes sense

On Sat, Sep 24, 2022 at 11:09 AM Malcolm Barrett @.***> wrote:

Interesting. Similar but not exactly the same as is. This is what you meant, yeah?

library(tipr)

IPW estimates without unmeasured confounder

estimates <- c(estimate = -12.5, conf.low = -13.8, conf.high = -11.3)

x <- adjust_coef_with_binary(

unlist(estimates),

exposed_confounder_prev = 0.25,

unexposed_confounder_prev = .05,

confounder_outcome_effect = -8

)

y <- adjust_coef(

unlist(estimates),

exposure_confounder_effect = 0.25 - .05,

confounder_outcome_effect = -8

)

tibble::tibble(x = x$effect_adjusted, y = y$effect_adjusted)

> # A tibble: 3 × 2

> x y

>

> 1 -10.2 -10.9

> 2 -11.5 -12.2

> 3 -9.03 -9.7

Created on 2022-09-24 with reprex v2.0.2 https://reprex.tidyverse.org

— Reply to this email directly, view it on GitHub https://github.com/LucyMcGowan/tipr/pull/12#issuecomment-1256991005, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACAKSGPKH25C3I227CQDRDLV74KS3ANCNFSM6AAAAAAQUN3IPU . You are receiving this because you commented.Message ID: @.***>

-- Lucy D'Agostino McGowan, PhD Assistant Professor Department of Statistical Sciences Wake Forest University ✉️ @.*** 🌐 lucymcgowan.com https://www.lucymcgowan.com

malcolmbarrett commented 2 years ago

That makes sense (and the two are identical when I use the updated code)! Ok, I tweaked it a little. This is a little silly, but I switched it to call adjust_coef() internally because that's intuitive to me. I also mentioned in the docs that they are the same in that case.

Regarding your second point re: assumptions, that only affects the interpretation, correct? If that's the case, I think we should mention it in the docs (and book chapter) but that they don't need to be separated out

LucyMcGowan commented 2 years ago

I don't think that is silly! In fact maybe that is what we should kind of push people towards because that one fits a bit better under any scenario. I'm not sure the best way to word the docs now, but basically exposure_confounder_effect could be the difference in means for a Normally distributed confounder with a variance of one OR it could be the beta coefficient for the exposure (X) from this model:

U ~ X + Z

where Z are the other measured confounders -- with this U can be any distribution AND need not be independent from Z so way easier 😂

LucyMcGowan commented 2 years ago
image

I've updated here in the last section