【问题标题】:Looping over unique pairs of elements in a list in R循环遍历R中列表中的唯一元素对
【发布时间】:2020-12-29 01:59:37
【问题描述】:

假设我有一个名为bb 的对象列表。我想在bb 中挑选每个唯一的元素对 并在some kind of function(称为convolve)中使用它们,如下所示:

## Below `bb` elements: `bma1` & `bma2` are used in the function:

con  <- convolve(dens1= bb$bma1$dposterior,
                 dens2= function(x){bb$bma2$dposterior(-x)},
                  cdf1= bb$bma1$pposterior,
                  cdf2= function(x){1 - bb$bma2$pposterior(-x)})

con$quantile(c(0.025, 0.975))

问题: bb 可以有任意数量的元素,但 convolve() 一次只接受两个元素,我想知道如何遍历 bb 列表的元素,这样所有bb 中的唯一对(在此示例中:bma1 & bma2; bma1 & bma3; bma2 &amp; bma3)被输入到 convolve()?

这是一个可重现的代码:

library("metafor")
library("bayesmeta")

dat <- escalc(measure="OR", ai=lh.le, bi=lh.re, ci=rh.le, 
              di=rh.re, data=dat.bourassa1996, add=1/2, to="all")

bma1 <- bayesmeta(dat[dat$sex=="combined",])
bma2 <- bayesmeta(dat[dat$sex=="male",])
bma3 <- bayesmeta(dat[dat$sex=="female",])

bb <- list(bma1 = bma1, bma2 = bma2, bma3 = bma3)

# The function (`source` if needed for full reproducibility)

source('https://raw.githubusercontent.com/rnorouzian/m/master/co.r')

con <- convolve(dens1= bb$bma1$dposterior,
                dens2= function(x){bb$bma2$dposterior(-x)},
                 cdf1= bb$bma1$pposterior,
                 cdf2= function(x){1 - bb$bma2$pposterior(-x)})

con$quantile(c(0.025, 0.975))

【问题讨论】:

  • 可能想看看?outer
  • 其实?combn在这里可能更有用。简化为矩阵,然后在结果上使用apply()

标签: r function loops for-loop purrr


【解决方案1】:

如果bb表示必须成对组合的数据帧,我们可以使用gtools::combinations()生成一个成对矩阵,并用它来驱动对convolve()的调用。

library("metafor")
library("bayesmeta")

dat <- escalc(measure="OR", ai=lh.le, bi=lh.re, ci=rh.le, 
              di=rh.re, data=dat.bourassa1996, add=1/2, to="all")

bma1 <- bayesmeta(dat[dat$sex=="combined",])
bma2 <- bayesmeta(dat[dat$sex=="male",])
bma3 <- bayesmeta(dat[dat$sex=="female",])

bb <- list(bma1 = bma1, bma2 = bma2, bma3 = bma3)

library(gtools)
comboMatrix <- combinations(length(bb),2) # unique pairs of elements in bb
comboMatrix

此时,comboMatrix 看起来像:

> comboMatrix
     [,1] [,2]
[1,]    1    2
[2,]    1    3
[3,]    2    3

我们继续使用原始帖子中提供的代码,将convolve() 函数包装在lapply() 中。我们使用表示comboMatrix 行维度的向量来驱动lapply(),我们将使用该向量为列表bb 中的元素对索引到第1 列和第2 列,以便在两组之间进行比较。

我们使用提取运算符的[[ 形式而不是$ 形式,因为我们需要使用变量替换(即comboMatrix[a,1]comboMatrix[a,2] 的结果)从列表@ 中提取适当的元素987654336@.

# The function (source if needed for full reproducibility)

source('https://raw.githubusercontent.com/rnorouzian/m/master/co.r')

conList <- lapply(1:nrow(comboMatrix),function(a){
 con <-    convolve(dens1 = bb[[comboMatrix[a,1]]]$dposterior,
              dens2 = function(x){bb[[comboMatrix[a,2]]]$dposterior(-x)},
              cdf1 = bb[[comboMatrix[a,1]]]$pposterior,
              cdf2 = function(x){1 - bb[[comboMatrix[a,2]]]$pposterior(-x)})
 con$quantile(c(0.025, 0.975))
})

此时conList 对象包含与convolve() 相比的每对数据帧的置信区间。

# name the output items
names(conList) <- unlist(lapply(1:nrow(comboMatrix),function(x){
     paste("group",comboMatrix[x,1],"vs",comboMatrix[x,2])
}))

conList

当我们打印对象时,我们会看到三组置信区间:

> conList
$`group 1 vs 2`
[1] -0.3564418  0.3685752

$`group 1 vs 3`
[1] -0.6560065  0.3069931

$`group 2 vs 3`
[1] -0.7298583  0.3589061

当我们通过运行原始帖子中包含的第一次比较代码来验证结果时,我们看到置信区间匹配。

con <- convolve(dens1= bb$bma1$dposterior,
                dens2= function(x){bb$bma2$dposterior(-x)},
                 cdf1= bb$bma1$pposterior,
                 cdf2= function(x){1 - bb$bma2$pposterior(-x)})

con$quantile(c(0.025, 0.975))

...和输出:

> con$quantile(c(0.025, 0.975))
[1] -0.3564418  0.3685752

第二次和第三次运行生成的置信区间也与lapply() 版本的结果相匹配。

# group 1 vs. 3
con <- convolve(dens1= bb$bma1$dposterior,
                dens2= function(x){bb$bma3$dposterior(-x)},
                cdf1= bb$bma1$pposterior,
                cdf2= function(x){1 - bb$bma3$pposterior(-x)})

con$quantile(c(0.025, 0.975))


# group 2 vs. 3 
con <- convolve(dens1= bb$bma2$dposterior,
                dens2= function(x){bb$bma3$dposterior(-x)},
                cdf1= bb$bma2$pposterior,
                cdf2= function(x){1 - bb$bma3$pposterior(-x)})

con$quantile(c(0.025, 0.975))

...和输出:

> # group 1 vs. 3
> con <- convolve(dens1= bb$bma1$dposterior,
+                 dens2= function(x){bb$bma3$dposterior(-x)},
+                 cdf1= bb$bma1$pposterior,
+                 cdf2= function(x){1 - bb$bma3$pposterior(-x)})
> 
> con$quantile(c(0.025, 0.975))
[1] -0.6560065  0.3069931
> # group 2 vs. 3 
> con <- convolve(dens1= bb$bma2$dposterior,
+                 dens2= function(x){bb$bma3$dposterior(-x)},
+                 cdf1= bb$bma2$pposterior,
+                 cdf2= function(x){1 - bb$bma3$pposterior(-x)})
> 
> con$quantile(c(0.025, 0.975))
[1] -0.7298583  0.3589061

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-11
    • 2018-09-05
    • 1970-01-01
    • 2010-12-09
    • 2017-02-08
    • 2017-02-11
    • 1970-01-01
    相关资源
    最近更新 更多