Skip to content

Commit 70f88e3

Browse files
committed
Fix index mapping bug in bpbounds_calc_tri_z3 and update examples
bpbounds_calc_tri_z3 was assigning p[2]→p100 and p[3]→p010 (and the corresponding pairs for z=1 and z=2), swapping the x=0,y=1 and x=1,y=0 cells relative to the (x,y,z) input ordering used by xtabs and bpbounds_calc_tri_z2. Corrected to match bpbounds_calc_tri_z2. Replace the hardcoded approximate conditional probabilities for the Meleady trivariate example with count-data-derived probabilities via xtabs, which satisfy the IV constraints under the corrected mapping. Update test expectations accordingly. Closes #3
1 parent 5699965 commit 70f88e3

4 files changed

Lines changed: 37 additions & 42 deletions

File tree

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
* **dplyr** removed as a soft dependency and instances of the magrittr/dplyr pipe, `%>%`, replaced with the native pipe, `|>`.
66

7+
* Fixed incorrect index mapping in `bpbounds_calc_tri_z3()`: the x=0,y=1 and x=1,y=0 conditional probability cells were swapped for each category of Z, giving wrong bounds for the trivariate 3-category instrument case (thanks @sachsmc).
8+
79
# bpbounds 0.1.6
810

911
* Tweak formatting of code in helpfile examples and vignette

R/bpbounds_calc_tri_z3.R

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
bpbounds_calc_tri_z3 <- function(p) {
22
# assuming that p is in the following order
33
# notation for conditional probabilities is p(y,x|z)
4+
# input vector uses (x,y,z) ordering, consistent with bpbounds_calc_tri_z2
45
p000 = p[1]
5-
p100 = p[2]
6-
p010 = p[3]
6+
p100 = p[3]
7+
p010 = p[2]
78
p110 = p[4]
89
p001 = p[5]
9-
p101 = p[6]
10-
p011 = p[7]
10+
p101 = p[7]
11+
p011 = p[6]
1112
p111 = p[8]
1213
p002 = p[9]
13-
p102 = p[10]
14-
p012 = p[11]
14+
p102 = p[11]
15+
p012 = p[10]
1516
p112 = p[12]
1617

1718
# bounds on probabilities

tests/testthat/test-bpbounds.R

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -231,44 +231,37 @@ test_that("Balke and Pearl Table 2 example: trivariate data with 2 category inst
231231
})
232232

233233

234-
# Meleady AJCN 2003; Trivariate data with 3 category instrument - Table 3 of paper ----
234+
# Meleady AJCN 2003; 3 category instrument - Table 3 of paper ----
235+
dat <- data.frame(
236+
count = c(341, 47, 297, 17, 63, 18, 272, 41, 269, 38, 56, 35),
237+
z = c(0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2),
238+
y = c(0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1),
239+
x = c(0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1)
240+
)
241+
longdat <- tidyr::uncount(dat, weights = count)
242+
235243
## Trivariate data
236-
mt3 <- c(.83, .05, .11, .01, .88, .06, .05, .01, .72, .05, .20, .03)
237-
p3 <- array(mt3,
238-
dim = c(2, 2, 3),
239-
dimnames = list(
240-
x = c(0, 1),
241-
y = c(0, 1),
242-
z = c(0, 1, 2)
243-
))
244-
p3 <- as.table(p3)
244+
xt3 <- xtabs(count ~ x + y + z, data = dat)
245+
p3 <- prop.table(xt3, margin = 3)
245246

246247
test_that("Mendelian randomization with 3 category instrument, trivariate data",
247248
{
248249
bpres <- bpbounds(p3)
249250
expect_true(bpres$inequality)
250-
expect_equal(bpres$bplb, -0.090, tol = 1e-4)
251-
expect_equal(bpres$bpub, 0.74, tol = 1e-4)
252-
expect_equal(bpres$p10low, 0.06, tol = 1e-4)
253-
expect_equal(bpres$p10upp, 0.12, tol = 1e-4)
254-
expect_equal(bpres$p11low, 0.03, tol = 1e-4)
255-
expect_equal(bpres$p11upp, 0.800, tol = 1e-4)
256-
expect_equal(bpres$crrlb, 0.25, tol = 1e-4)
257-
expect_equal(bpres$crrub, 13.3333, tol = 1e-4)
251+
expect_equal(bpres$bplb, -0.3101, tol = 1e-4)
252+
expect_equal(bpres$bpub, 0.4622, tol = 1e-4)
253+
expect_equal(bpres$p10low, 0.4332, tol = 1e-4)
254+
expect_equal(bpres$p10upp, 0.5136, tol = 1e-4)
255+
expect_equal(bpres$p11low, 0.2035, tol = 1e-4)
256+
expect_equal(bpres$p11upp, 0.8953, tol = 1e-4)
257+
expect_equal(bpres$crrlb, 0.3962, tol = 1e-4)
258+
expect_equal(bpres$crrub, 2.0670, tol = 1e-4)
258259
expect_false(bpres$monoinequality)
259260
sbp <- summary(bpres)
260261
print(sbp)
261262
})
262263

263264
## Bivariate data
264-
dat <- data.frame(
265-
count = c(341, 47, 297, 17, 63, 18, 272, 41, 269, 38, 56, 35),
266-
z = c(0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2),
267-
y = c(0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1),
268-
x = c(0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1)
269-
)
270-
longdat <- tidyr::uncount(dat, weights = count)
271-
272265
gtab <- xtabs(~ y + z, data = longdat)
273266
gp <- prop.table(gtab, margin = 2)
274267
gp

vignettes/bpbounds.Rmd

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -138,18 +138,17 @@ Mendelian randomization is an approach in epidemiology due to @daveysmith-ije-20
138138
This example uses data from @meleady-ajcn-2003. It is trivariate data with a 3-category instrument and binary phenotype and outcomes. The instrument is the 677CT polymorphism (rs1801133) in the Methylenetetrahydrofolate Reductase gene, involved in folate metabolism, as an instrumental variable to investigate the effect of homocysteine on cardiovascular
139139
disease.
140140

141-
The data are presented to us as conditional probabilities, so we take care to enter them in the correct position in the vectors.
141+
The data from Table 3 of @meleady-ajcn-2003 are given as counts below.
142142

143143
```{r}
144-
mt3 <- c(.83, .05, .11, .01, .88, .06, .05, .01, .72, .05, .20, .03)
145-
p3 <- array(mt3,
146-
dim = c(2, 2, 3),
147-
dimnames = list(
148-
x = c(0, 1),
149-
y = c(0, 1),
150-
z = c(0, 1, 2)
151-
))
152-
p3 <- as.table(p3)
144+
dat <- data.frame(
145+
count = c(341, 47, 297, 17, 63, 18, 272, 41, 269, 38, 56, 35),
146+
z = c(0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2),
147+
y = c(0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1),
148+
x = c(0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1)
149+
)
150+
xt3 <- xtabs(count ~ x + y + z, data = dat)
151+
p3 <- prop.table(xt3, margin = 3)
153152
bpres3 <- bpbounds(p3)
154153
sbp3 <- summary(bpres3)
155154
print(sbp3)

0 commit comments

Comments
 (0)