【问题标题】:Extracting Confidence Intervals data.table提取置信区间 data.table
【发布时间】:2023-07-26 21:25:02
【问题描述】:

我想要做的是为比例的上下置信区间设置列。

这是我所做的:

> #Create some sample data
> Frustration <- data.table(group = c('A','B','C'), trials = c(363,1398,139), surg = c(57,276,18))
> Frustration
   group trials surg
1:     A    363   57
2:     B   1398  276
3:     C    139   18
> 
> #try to get confidence levels. what I am expecting is CI to be a list of 2 elements, for each value of group, but I don't think that is working
> F2 <- Frustration[, .(CI = prop.test(surg, trials, conf.level = .75)['conf.int']), by = .(group)]
> F2
   group                    CI
1:     A   0.1350140,0.1816828
2:     B   0.1851178,0.2103210
3:     C 0.09701967,0.16972056
> 
> #lower is still a list here - I am stumped
> F3 <- F2[, .(lower = CI[[1]]), by = .(group)]
> F3
   group                 lower
1:     A   0.1350140,0.1816828
2:     B   0.1851178,0.2103210
3:     C 0.09701967,0.16972056

我认为混淆与列表有关,以及数据表如何处理返回。

感谢您的帮助,

大卫

【问题讨论】:

    标签: r data.table confidence-interval


    【解决方案1】:

    CI 是一个 list 列。我们可以使用transpose 并赋值(:=

    library(data.table)
    F2[, c('lower', 'upper') := data.table::transpose(CI)][, CI := NULL][]
    #Key: <group>
    #    group      lower     upper
    #   <char>      <num>     <num>
    #1:      A 0.13501400 0.1816828
    #2:      B 0.18511780 0.2103210
    #3:      C 0.09701967 0.1697206
    

    【讨论】:

    • 这就是我要找的函数,transpose
    • 所以这行得通,但我不明白。我的想法是不正确的,对于每个组,CI 将是单独的 2 元素列表,因此将第一个元素设为较低的元素会起作用。转置意味着对于每个组,CI 是别的东西,但是什么?
    • @DavidF 您可以打印F2$CI,这是一个list 列,每个列表元素中有两个元素。 data.table::transpose(F2$CI) 通过将列表的每个对应元素连接到一个向量来更改 list 的长度,即每个列表元素的第一个元素由单个向量组成,同样的第二个元素,即下部和上部组件重新组合为两个新列表中的向量
    【解决方案2】:

    另一种解决方案有效,但这里有一个简单的单行:

    library(data.table)
    
    Frustration <- data.table(group = c('A','B','C'), trials = c(363,1398,139),
                              surg = c(57,276,18))
    
    Frustration[, c("lower", "upper") := 
                  as.list(prop.test(surg, trials, conf.level = .75)$conf.int), 
                by=group][]
    #>    group trials surg      lower     upper
    #> 1:     A    363   57 0.13501400 0.1816828
    #> 2:     B   1398  276 0.18511780 0.2103210
    #> 3:     C    139   18 0.09701967 0.1697206
    

    甚至更简单,但您必须进行一些重命名:

    Frustration[, as.list(prop.test(surg, trials, conf.level = .75)$conf.int), by=group]
    #>    group         V1        V2
    #> 1:     A 0.13501400 0.1816828
    #> 2:     B 0.18511780 0.2103210
    #> 3:     C 0.09701967 0.1697206
    

    【讨论】:

    • 谢谢。这对我来说更有意义,但我仍然在 as.list 中苦苦挣扎。 prop.test 不返回列表列表吗?当我尝试 Frustration[, prop.test(surg, trial, conf.level = .75)['conf.int'], by=group] 我得到 8 行,而不是你的 4 行。我认为这就是为什么解决方案1中需要转置,但我仍然很困惑。谢谢。
    • 不,如果你这样做 class(prop.test(2, 10)$confint),你会看到它返回一个长度为 2 的数字向量。通过将它包装在 as.list 中,我将它转换为一个包含两个元素的列表,每个元素这是一个单一的数值。 data.table 看到一个列表,并将该列表的每个元素解释为一列。由于每列只有 1 个元素,因此您得到 1 行。相反,您的调用包含单个元素(长度为 2 的向量),因此 data.table 将其解释为您要求 1 列 2 行。