【问题标题】:calculating confidence intervals for a median in oracle在 oracle 中计算中位数的置信区间
【发布时间】:2016-01-10 12:13:09
【问题描述】:

我正在尝试生成一个 oracle sql 查询,它不仅可以计算年龄中位数,还可以计算 95% 的置信度。在这种情况下,要添加并发症需要跨组进行 我有一张他们的年龄和性别的表格。我想确定每个组的中位年龄及其 95% 置信区间。 我目前失败的尝试如下。

select gender,
       median(age),
       count(*),
       percentile_cont(ROUND((COUNT(*)/2)-1.96*sqrt(COUNT(*))/2)/COUNT(*)) 
         within GROUP (ORDER BY age) lowmedianage,
       percentile_cont(ROUND((COUNT(*)/2)+1.96*sqrt(COUNT(*))/2)/COUNT(*)) 
         within GROUP (ORDER BY age) highmedianage
  from persontable
  group by gender

我收到一个错误,而不是 GROUP BY 表达式。

【问题讨论】:

    标签: oracle median


    【解决方案1】:

    使用this book 中的公式,我以以下查询结尾(我不确定你是否能很好地处理低和高范围;我的解释是你计算了一个序列号的范围,你必须查找这些位置的值)。

    with tab as 
    -- add sequence per group
    (
    select gender, age,
    row_number() over (PARTITION  BY gender order by  gender, age) as seq
    from persontable
    ),
    -- get count
    N as (select gender, count(*) cnt from persontable group by gender),
    -- calculate sequence numbers of the CI
    ci_seq as (
    select gender,
    round(cnt/2 - (1.96 * sqrt(cnt)/2)) r,
    round(1 + cnt/2 + (1.96 * sqrt(cnt)/2)) s
    from n),
    -- calculate median
    med as (
    select 
      gender,
      median(age) median_age
    from  persontable
    group by gender),
    med2 as (
    select med.gender, median_age, r, s
    from med 
    join ci_seq on med.gender = ci_seq.gender 
    )
    select gender, median_age,
    (select age from tab where seq = r and gender = med2.gender) ci_from,
    (select age from tab where seq = s and gender = med2.gender) ci_to
    from med2
    ;
    

    另请注意,该公式仅近似于 CI。您也可以查看this thread 以了解替代计算。

    【讨论】:

    • 几乎可行,但根据我的数据,上限和下限不包含男性的中位数。如果我将 cnt/2 m, 添加到 ci_seq 并将 (select age from tab where seq=m) 中值添加到最终查询中,则返回的男性中值不等于同一查询中的中值年龄,但它确实与女性匹配。有什么想法吗?
    • 你的问题,真的很有帮助,回复是当性别改变时 seq 不会返回 1 所以当你尝试匹配 seq 时,你总是在这种情况下查找第一个性别为女性。当性别改变时,不知道如何让 seq 返回 1。这将回答问题
    • @Tony - 我的错,我只测试了一种性别:( 我修复了查询,请参阅row_number() over (PARTITION BY gender order by gender, age) as seq 中添加的 PARTITION BY。这使得 seq 包装了性别。HTH
    【解决方案2】:

    这里的问题是您将函数 count 作为 percentile_cont 的参数,它需要一个常量,并且该常量必须是 group by 子句的一部分。您可能可以在此处使用子查询。类似的东西:

    select gender, median(age), count(*),
           percentile_cont(low) within GROUP (ORDER BY age) lowmedianage,
           percentile_cont(high) within GROUP (ORDER BY age) highmedianage
      from (select age, gender,
                   ROUND((COUNT(*)/2)-1.96*sqrt(COUNT(*))/2)/COUNT(*) low,
                   ROUND((COUNT(*)/2)+1.96*sqrt(COUNT(*))/2)/COUNT(*) high
              from persontable
             group by age, gender)
     group by gender, low, high
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-01
      • 1970-01-01
      • 2015-08-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-23
      相关资源
      最近更新 更多