1 of 94

Applied Demonstration of the tipr R Package

Lucy D’Agostino McGowan

@LucyStats�

Department of Mathematics & Statistics, Wake Forest University

2 of 94

lucymcgowan.com/talk

3 of 94

Based on work completed jointly with Robert Greevy

@ Vanderbilt University

4 of 94

TABLE OF CONTENTS

THE DATA

TIPPING POINT ANALYSES

02

GETTING TO KNOW tipr

03

USING tipr WITH A KNOWN CONFOUNDER

04

USING tipr WITH AN UNKNOWN CONFOUNDER

05

tipr + broom

06

01

VA Health Record data on diabetes drug and cancer incidence

A bit on tipping point analyses

Some basic usage of the tipr package

Using tipr when we know we were missing something

Using tipr when we don’t know what we may be missing

Using tipr with the broom package

5 of 94

01

THE DATA

6 of 94

7 of 94

QUESTION

Metformin

Cancer

VERSUS SULFONYLUREAS

8 of 94

ANALYSIS

  • New-user design
  • Matched 42,217 new metformin users to 42,217 new sulfonylurea users
  • Fit adjusted Cox proportional hazards model on the matched cohort

9 of 94

RESULTS

Lung Cancer

0.87 (0.79, 0.96)

Liver Cancer

0.46 (0.37, 0.57)

Colorectal Cancer

0.86 (0.75, 0.99)

OUTCOME

METFORMIN� (ADJ HAZARD RATIO)

10 of 94

RESULTS

Lung Cancer

0.87 (0.79, 0.96)

Liver Cancer

0.46 (0.37, 0.57)

Colorectal Cancer

0.86 (0.75, 0.99)

OUTCOME

METFORMIN� (ADJ HAZARD RATIO)

11 of 94

RESULTS

Lung Cancer

0.87 (0.79, 0.96)

Liver Cancer

0.46 (0.37, 0.57)

Colorectal Cancer

0.86 (0.75, 0.99)

OUTCOME

METFORMIN� (ADJ HAZARD RATIO)

12 of 94

02

TIPPING POINT ANALYSES

13 of 94

Quantifying unmeasured confounding

14 of 94

WHAT YOU NEED

EXPOSURE

OUTCOME

EFFECT

OUTCOME

UNMEASURED

CONFOUNDER

EFFECT

EXPOSURE

UNMEASURED

CONFOUNDER

EFFECT

15 of 94

TIPPING POINT

What will tip our confidence bound to cross 1?

16 of 94

WHAT YOU NEED

EXPOSURE

OUTCOME

EFFECT

OUTCOME

UNMEASURED

CONFOUNDER

EFFECT

EXPOSURE

UNMEASURED

CONFOUNDER

EFFECT

17 of 94

WHAT YOU NEED

EXPOSURE

OUTCOME

EFFECT

OUTCOME

UNMEASURED

CONFOUNDER

EFFECT

EXPOSURE

UNMEASURED

CONFOUNDER

EFFECT

18 of 94

TIPPING POINT

19 of 94

TIPPING POINT

relative risk - the unmeasured confounder-outcome effect

20 of 94

TIPPING POINT

relative risk* - the unmeasured confounder-outcome effect

*built for RRs, but can work for ORs and HRs

21 of 94

WHAT YOU NEED

EXPOSURE

OUTCOME

EFFECT

OUTCOME

UNMEASURED

CONFOUNDER

EFFECT

EXPOSURE

UNMEASURED

CONFOUNDER

EFFECT

22 of 94

TIPPING POINT

limiting bound (bound closest to the null)

23 of 94

WHAT YOU NEED

EXPOSURE

OUTCOME

EFFECT

OUTCOME

UNMEASURED

CONFOUNDER

EFFECT

EXPOSURE

UNMEASURED

CONFOUNDER

EFFECT

24 of 94

TIPPING POINT

standardized mean difference of the unmeasured confounder between the exposed and unexposed groups

25 of 94

WHAT YOU NEED

EXPOSURE

OUTCOME

EFFECT

OUTCOME

UNMEASURED

CONFOUNDER

EFFECT

EXPOSURE

UNMEASURED

CONFOUNDER

EFFECT

26 of 94

TIPPING POINT

27 of 94

TIPPING POINT

28 of 94

TIPPING POINT

29 of 94

TIPPING POINT

30 of 94

TIPPING POINT

31 of 94

03

GETTING TO KNOW tipr

32 of 94

install.packages("tipr")

devtools::install_github("LucyMcGowan/tipr")

33 of 94

Main function

tip()

  • d: a data frame that includes the observed confidence bounds
  • smd:scaled mean difference between the unmeasured confounder in the exposed and unexposed population
  • outcome_association:association between the unmeasured confounder and outcome

34 of 94

Main function

tip()

  • d: a data frame that includes the observed confidence bounds
  • smd:scaled mean difference between the unmeasured confounder in the exposed and unexposed population
  • outcome_association:association between the unmeasured confounder and outcome

35 of 94

WHAT YOU NEED

EXPOSURE

OUTCOME

EFFECT

OUTCOME

UNMEASURED

CONFOUNDER

EFFECT

EXPOSURE

UNMEASURED

CONFOUNDER

EFFECT

36 of 94

Main function

tip()

  • d: a data frame that includes the observed confidence bounds
  • smd:scaled mean difference between the unmeasured confounder in the exposed and unexposed population
  • outcome_association:association between the unmeasured confounder and outcome

37 of 94

WHAT YOU NEED

EXPOSURE

OUTCOME

EFFECT

OUTCOME

UNMEASURED

CONFOUNDER

EFFECT

EXPOSURE

UNMEASURED

CONFOUNDER

EFFECT

38 of 94

Main function

tip()

  • d: a data frame that includes the observed confidence bounds
  • smd:scaled mean difference between the unmeasured confounder in the exposed and unexposed population
  • outcome_association:association between the unmeasured confounder and outcome

39 of 94

WHAT YOU NEED

EXPOSURE

OUTCOME

EFFECT

OUTCOME

UNMEASURED

CONFOUNDER

EFFECT

EXPOSURE

UNMEASURED

CONFOUNDER

EFFECT

40 of 94

Main function

tip()

  • d: a data frame that includes the observed confidence bounds
  • smd:scaled mean difference between the unmeasured confounder in the exposed and unexposed population
  • outcome_association:association between the unmeasured confounder and outcome

41 of 94

Main function

tip()

  • d: a data frame that includes the observed confidence bounds
  • smd:scaled mean difference between the unmeasured confounder in the exposed and unexposed population
  • outcome_association:association between the unmeasured confounder and outcome

specify one, it will estimate the other

42 of 94

Main function

tip()

  • d: a data frame that includes the observed confidence bounds
  • smd:scaled mean difference between the unmeasured confounder in the exposed and unexposed population
  • outcome_association:association between the unmeasured confounder and outcome

specify two, it will estimate the number of unmeasured confounders needed to tip

43 of 94

Main function

tip_with_binary()

  • d: a data frame that includes the observed confidence bounds
  • exposed_p:prevelance of the unmeasured confounder in the exposed population
  • unexposed_p:prevelance of the unmeasured confounder in the unexposed population
  • outcome_association:association between the unmeasured confounder and outcome

44 of 94

Main function

tip_with_binary()

  • d: a data frame that includes the observed confidence bounds
  • exposed_p:prevelance of the unmeasured confounder in the exposed population
  • unexposed_p:prevelance of the unmeasured confounder in the unexposed population
  • outcome_association:association between the unmeasured confounder and outcome

45 of 94

WHAT YOU NEED

EXPOSURE

OUTCOME

EFFECT

OUTCOME

UNMEASURED

CONFOUNDER

EFFECT

EXPOSURE

UNMEASURED

CONFOUNDER

EFFECT

46 of 94

Main function

tip_with_binary()

  • d: a data frame that includes the observed confidence bounds
  • exposed_p:prevelance of the unmeasured confounder in the exposed population
  • unexposed_p:prevelance of the unmeasured confounder in the unexposed population
  • outcome_association:association between the unmeasured confounder and outcome

specify two, it will estimate the other

47 of 94

Main function

tip_with_binary()

  • d: a data frame that includes the observed confidence bounds
  • exposed_p:prevelance of the unmeasured confounder in the exposed population
  • unexposed_p:prevelance of the unmeasured confounder in the unexposed population
  • outcome_association:association between the unmeasured confounder and outcome

specify three, it will estimate the # of unmeasured confounders needed

48 of 94

04

USING tipr, WITH A KNOWN CONFOUNDER

49 of 94

RESULTS

Lung Cancer

0.87 (0.79, 0.96)

Liver Cancer

0.46 (0.37, 0.57)

Colorectal Cancer

0.86 (0.75, 0.99)

OUTCOME

METFORMIN� (ADJ HAZARD RATIO)

50 of 94

What if there is residual confounding for smoking?

51 of 94

Murff, HJ, Roumie, CL, Greevy, RA, Hackstadt, AJ, D’Agostino McGowan, LE., Hung, AM, ... & Griffin, MR. (2018). Metformin use and incidence cancer risk: evidence for a selective protective effect against liver cancer. Cancer Causes & Control, 29(9), 823-832.

52 of 94

This is likely an undercount for a veteran population

Murff, HJ, Roumie, CL, Greevy, RA, Hackstadt, AJ, D’Agostino McGowan, LE., Hung, AM, ... & Griffin, MR. (2018). Metformin use and incidence cancer risk: evidence for a selective protective effect against liver cancer. Cancer Causes & Control, 29(9), 823-832.

53 of 94

What if smoking is differentially undercounted with 8% unidentified smokers among Metformin users and 9% among Sulfonylurea users?

54 of 94

library(tipr)

tip_with_binary(data.frame(conf.low = 0.79,

conf.high = 0.96),

exposed_p = .08,

unexposed_p = .10)

55 of 94

library(tipr)

tip_with_binary(data.frame(conf.low = 0.79,

conf.high = 0.96),

exposed_p = .08,

unexposed_p = .10)

56 of 94

RESULTS

Lung Cancer

0.87 (0.79, 0.96)

Liver Cancer

0.46 (0.37, 0.57)

Colorectal Cancer

0.86 (0.75, 0.99)

OUTCOME

METFORMIN� (ADJ HAZARD RATIO)

57 of 94

library(tipr)

tip_with_binary(data.frame(conf.low = 0.79,

conf.high = 0.96),

exposed_p = .08,

unexposed_p = .10)

58 of 94

What if smoking is differentially undercounted with 8% unidentified smokers among Metformin users and 10% among Sulfonylurea users?

59 of 94

library(tipr)

tip_with_binary(data.frame(conf.low = 0.79,

conf.high = 0.96),

exposed_p = .08,

unexposed_p = .10)

60 of 94

#> The observed effect (0.79, 0.96) WOULD be tipped by 1 unmeasured confounder

#> with the following specifications:

#> * estimated prevalence of the unmeasured confounder in the exposed population: 0.08

#> * estimated prevalence of the unmeasured confounder in the unexposed population: 0.1

#> * estimated association between the unmeasured confounder and the outcome: 3.5

#> # A tibble: 1 x 6

#> observed_lb observed_ub exposed_p unexposed_p outcome_association n_unmeasured_confounders

#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>

#> 0.79 0.96 0.08 0.1 3.5 1

61 of 94

#> The observed effect (0.79, 0.96) WOULD be tipped by 1 unmeasured confounder

#> with the following specifications:

#> * estimated prevalence of the unmeasured confounder in the exposed population: 0.08

#> * estimated prevalence of the unmeasured confounder in the unexposed population: 0.1

#> * estimated association between the unmeasured confounder and the outcome: 3.5

#> # A tibble: 1 x 6

#> observed_lb observed_ub exposed_p unexposed_p outcome_association n_unmeasured_confounders

#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>

#> 0.79 0.96 0.08 0.1 3.5 1

62 of 94

If smoking were differentially undercounted, with 8% of unidentified smokers among metformin users and 10% among sulfonylureas users, this residual smoking would need to have an association with lung cancer indicence of 3.5 to tip this analysis at the 5% level, rendering it inconclusive. Given that associations between lung cancer and smoking have been reported to be quite large, we cannot rule out unmeasured confounding.

63 of 94

If smoking were differentially undercounted, with 8% of unidentified smokers among metformin users and 10% among sulfonylureas users, this residual smoking would need to have an association with lung cancer indicence of 3.5 to tip this analysis at the 5% level, rendering it inconclusive. Given that associations between lung cancer and smoking have been reported to be quite large, we cannot rule out unmeasured confounding.

*Note in this particular paper, we adjusted for COPD and numerous other cardiovascular conditions which are highly associated with smoking and would potentially pick up much of that residual confounding.

64 of 94

05

USING tipr, WITH AN UNKNOWN CONFOUNDER

65 of 94

RESULTS

Lung Cancer

0.87 (0.79, 0.96)

Liver Cancer

0.46 (0.37, 0.57)

Colorectal Cancer

0.86 (0.75, 0.99)

OUTCOME

METFORMIN� (ADJ HAZARD RATIO)

66 of 94

What if there is an unmeasured confounder that increased one’s liver cancer risk with an association between liver cancer and the unmeasured confounder of 2?

67 of 94

tip(data.frame(conf.low = 0.37,

conf.high = 0.57),

outcome_association = 2)

68 of 94

#> The observed effect (0.37, 0.57) WOULD be tipped by 1 unmeasured confounder

#> with the following specifications:

#> * estimated standardized mean difference between the unmeasured confounder

#> in the exposed population and unexposed population: -0.81

#> * estimated association between the unmeasured confounder and the outcome: 2

#> # A tibble: 1 x 5

#> observed_lb observed_ub smd outcome_association n_unmeasured_confounders

#> <dbl> <dbl> <dbl> <dbl> <dbl>

#> 0.37 0.570 -0.811 2 1

69 of 94

#> The observed effect (0.37, 0.57) WOULD be tipped by 1 unmeasured confounder

#> with the following specifications:

#> * estimated standardized mean difference between the unmeasured confounder

#> in the exposed population and unexposed population: -0.81

#> * estimated association between the unmeasured confounder and the outcome: 2

#> # A tibble: 1 x 5

#> observed_lb observed_ub smd outcome_association n_unmeasured_confounders

#> <dbl> <dbl> <dbl> <dbl> <dbl>

#> 0.37 0.570 -0.811 2 1

70 of 94

Love Plot

Murff, HJ, Roumie, CL, Greevy, RA, Hackstadt, AJ, D’Agostino McGowan, LE., Hung, AM, ... & Griffin, MR. (2018). Metformin use and incidence cancer risk: evidence for a selective protective effect against liver cancer. Cancer Causes & Control, 29(9), 823-832.

71 of 94

Murff, HJ, Roumie, CL, Greevy, RA, Hackstadt, AJ, D’Agostino McGowan, LE., Hung, AM, ... & Griffin, MR. (2018). Metformin use and incidence cancer risk: evidence for a selective protective effect against liver cancer. Cancer Causes & Control, 29(9), 823-832.

72 of 94

#> The observed effect (0.37, 0.57) WOULD be tipped by 1 unmeasured confounder

#> with the following specifications:

#> * estimated standardized mean difference between the unmeasured confounder

#> in the exposed population and unexposed population: -0.81

#> * estimated association between the unmeasured confounder and the outcome: 2

#> # A tibble: 1 x 5

#> observed_lb observed_ub smd outcome_association n_unmeasured_confounders

#> <dbl> <dbl> <dbl> <dbl> <dbl>

#> 0.37 0.570 -0.811 2 1

73 of 94

Love Plot

0.4

0.5

0.6

0.7

0.8

Murff, HJ, Roumie, CL, Greevy, RA, Hackstadt, AJ, D’Agostino McGowan, LE., Hung, AM, ... & Griffin, MR. (2018). Metformin use and incidence cancer risk: evidence for a selective protective effect against liver cancer. Cancer Causes & Control, 29(9), 823-832.

74 of 94

What if there were multiple independent unmeasured confounders that increased one’s cancer risk with an association of 2 and had a SMD of -0.1?

75 of 94

tip(data.frame(conf.low = 0.37,

conf.high = 0.57),

outcome_association = 2,

smd = -0.1)

76 of 94

#> The observed effect (0.37, 0.57) WOULD be tipped by 8 unmeasured confounders

#> with the following specifications:

#> * estimated standardized mean difference between the unmeasured confounder

#> in the exposed population and unexposed population: -0.1

#> * estimated association between the unmeasured confounder and the outcome: 2

#> # A tibble: 1 x 5

#> observed_lb observed_ub smd outcome_association n_unmeasured_confounders

#> <dbl> <dbl> <dbl> <dbl> <dbl>

#> 1 0.37 0.570 -0.1 2 8.11

77 of 94

#> The observed effect (0.37, 0.57) WOULD be tipped by 8 unmeasured confounders

#> with the following specifications:

#> * estimated standardized mean difference between the unmeasured confounder

#> in the exposed population and unexposed population: -0.1

#> * estimated association between the unmeasured confounder and the outcome: 2

#> # A tibble: 1 x 5

#> observed_lb observed_ub smd outcome_association n_unmeasured_confounders

#> <dbl> <dbl> <dbl> <dbl> <dbl>

#> 1 0.37 0.570 -0.1 2 8.11

78 of 94

An unmeasured confounder with an association with liver cancer incidence of 2 and a standardized mean difference between the metformin users and sulfonylurea users of -0.81 would tip this analysis at the 5% level, rendering it inconclusive. Alternatively, you would need 8 independent unmeasured confounders, each with with an association with liver cancer incidence of 2 and a standardized mean difference -0.1 to tip this analysis.

79 of 94

RESULTS

Lung Cancer

0.87 (0.79, 0.96)

Liver Cancer

0.46 (0.37, 0.57)

Colorectal Cancer

0.86 (0.75, 0.99)

OUTCOME

METFORMIN� (ADJ HAZARD RATIO)

80 of 94

What if there is an unmeasured confounder that increased one’s colorectal cancer risk with an assoication of 2?

81 of 94

tip(data.frame(conf.low = 0.75,

conf.high = 0.99),

outcome_association = 2)

82 of 94

#> The observed effect (0.75, 0.99) WOULD be tipped by 1 unmeasured confounder

#> with the following specifications:

#> * estimated standardized mean difference between the unmeasured confounder

#> in the exposed population and unexposed population: -0.01

#> * estimated association between the unmeasured confounder and the outcome: 2

#> # A tibble: 1 x 5

#> observed_lb observed_ub smd outcome_association n_unmeasured_confounders

#> <dbl> <dbl> <dbl> <dbl> <dbl>

#> 1 0.75 0.99 -0.0145 2 1

83 of 94

#> The observed effect (0.75, 0.99) WOULD be tipped by 1 unmeasured confounder

#> with the following specifications:

#> * estimated standardized mean difference between the unmeasured confounder

#> in the exposed population and unexposed population: -0.01

#> * estimated association between the unmeasured confounder and the outcome: 2

#> # A tibble: 1 x 5

#> observed_lb observed_ub smd outcome_association n_unmeasured_confounders

#> <dbl> <dbl> <dbl> <dbl> <dbl>

#> 1 0.75 0.99 -0.0145 2 1

84 of 94

An unmeasured confounder with an association with colorectal cancer indicence of 2 and a standardized mean difference between the metformin users and sulfonylurea users of -0.1 would tip this analysis at the 5% level, rendering it inconclusive.

85 of 94

06

tipr + broom

86 of 94

library(tipr)

library(broom)

glm(vs ~ am + wt, data = mtcars, family = "binomial") %>%

broom::tidy(conf.int = TRUE, exponentiate = TRUE) %>%

dplyr::filter(term == "am") %>%

tip(outcome_association = 2.5)

87 of 94

library(tipr)

library(broom)

glm(vs ~ am + wt, data = mtcars, family = "binomial") %>%

broom::tidy(conf.int = TRUE, exponentiate = TRUE) %>%

dplyr::filter(term == "am") %>%

tip(outcome_association = 2.5)

88 of 94

library(tipr)

library(broom)

glm(vs ~ am + wt, data = mtcars, family = "binomial") %>%

broom::tidy(conf.int = TRUE, exponentiate = TRUE) %>%

dplyr::filter(term == "am") %>%

tip(outcome_association = 2.5)

89 of 94

library(tipr)

library(broom)

glm(vs ~ am + wt, data = mtcars, family = "binomial") %>%

broom::tidy(conf.int = TRUE, exponentiate = TRUE) %>%

dplyr::filter(term == "am") %>%

tip(outcome_association = 2.5)

90 of 94

library(tipr)

library(broom)

glm(vs ~ am + wt, data = mtcars, family = "binomial") %>%

broom::tidy(conf.int = TRUE, exponentiate = TRUE) %>%

dplyr::filter(term == "am") %>%

tip(outcome_association = 2.5)

91 of 94

#> The observed effect (0, 0.16) WOULD be tipped by 1 unmeasured confounder

#> with the following specifications:

#> * estimated standardized mean difference between the unmeasured confounder

#> in the exposed population and unexposed population: -2.03

#> * estimated association between the unmeasured confounder and the outcome: 2.5

#> # A tibble: 1 x 5

#> observed_lb observed_ub smd outcome_association n_unmeasured_confounders

#> <dbl> <dbl> <dbl> <dbl> <dbl>

#> 1 0.00000226 0.156 -2.03 2.5 1

92 of 94

library(tipr)

library(broom)

glm(vs ~ am + wt, data = mtcars, family = "binomial") %>%

broom::tidy(conf.int = TRUE, exponentiate = TRUE) %>%

dplyr::filter(term == "am") %>%

tip(outcome_association = 2.5, verbose = FALSE)

93 of 94

#> # A tibble: 1 x 5

#> observed_lb observed_ub smd outcome_association n_unmeasured_confounders

#> <dbl> <dbl> <dbl> <dbl> <dbl>

#> 1 0.00000226 0.156 -2.03 2.5 1

94 of 94

THANKS

@LucyStats

Lucy D’Agostino McGowan�

Department of Mathematics & Statistics, Wake Forest University

CREDITS: This presentation template was created by Slidesgo, including icons by Flaticon, infographics & images by Freepik