【问题标题】:Conditional percentile with index function带索引函数的条件百分位数
【发布时间】:2018-11-16 01:08:48
【问题描述】:

我有一个针对不同国家/地区类别的面板数据集,每个类别都有一些分数。我需要计算分数的百分位排名,但只针对同一国家/地区的分数。我设法编写了一个数组函数来完成这项工作,但它似乎错误地计算了百分位数。任何想法为什么?

数据集

Country Score   Manual percentiles  Array-function percentiles
AT      0.211   0.555               0.368
AT      0.090   0.111               0.157
AT      0.722   0.888               0.842
AT      0.241   0.666               0.421
AT      0.099   0.222               0.21
AT      0.138   0.444               0.315
AT      0.068   0                   0
AT      0.136   0.333               0.263
AT      0.461   0.777               0.736
AT      0.982   1                   1
BE      0.068   0                   0.052
BE      0.316   0.333               0.526
BE      0.304   0.222               0.473
BE      0.072   0.111               0.105
BE      0.703   0.777               0.789
BE      0.419   0.444               0.578
BE      0.788   0.888               0.894
BE      0.817   1                   0.947
BE      0.444   0.666               0.684
BE      0.425   0.555               0.631

我计算的手动百分位数:

=PERCENTRANK($B$2:$B$11;B2) for Country = "AT"
=PERCENTRANK($B$12:$B$21;B12) for COuntry = "BE"

我输入数组函数百分位数的数组公式(并使用 Ctrl + Shift + Enter 输入)

=PERCENTRANK(IF($A$2:$A$21=INDEX($A$2:$A$21;ROW()-1);$B$2:$B$21);
INDEX($B$2:$B$21;ROW()-1))

结果似乎抓住了数据的要点,但实际上是不同的。任何想法为什么?我发现如果我把 INDEX($A$2:$A$21;ROW()-1) 替换成“AT”或者“BE”,结果是一样的。

【问题讨论】:

    标签: excel indexing conditional percentile


    【解决方案1】:

    您可以在 vba 中创建一个自定义函数,其操作类似于 sumif 公式。

    下面是我以前做过的一个例子。那么您可以在现有子程序中引用该函数,或直接在工作簿中使用它。

    请注意,如果您在大数据范围内使用它,它会占用资源。

    Option Explicit
    Dim Data_range As Range
    Dim Criteria_range As Range
    Dim d_array As Variant
    Dim c_array As Variant
    Dim p_array() As Double
    Dim Criteria As Range
    Dim k As Double
    Dim c As Long
    Dim i As Long
    
    Function PERCENTILEIF(Data_range, Criteria_range, Criteria, k)
    
    ' Define Inputs
        d_array = Data_range.Value
        c_array = Criteria_range.Value
    
    ' Seed Percentile array
        c = 0
        ReDim Preserve p_array(c)
    
    ' Loop through range, look for matching criteria, If found add to p_array
        For i = 1 To UBound(c_array, 1)
            If c_array(i, 1) = Criteria.Value Then
                ReDim Preserve p_array(0 To c)
                p_array(c) = d_array(i, 1)
                c = c + 1
            End If
        Next
    
    ' worksheet percentile function of p_array
        PERCENTILEIF = Application.WorksheetFunction.Percentile(p_array, k)
    
    ' Clean up
        c = 0
        Erase d_array
        Erase c_array
        Erase p_array
    
    End Function
    

    【讨论】:

      【解决方案2】:

      如果我从A1 开始复制您的数据,这对我有用(仍然使用 ctrl+shift+enter):

      =PERCENTRANK(IF($A$2:$A$21=A2;$B$2:$B$21);B2)
      

      【讨论】:

      • 技术上是的,但我发现这个实现有点缺乏远见。一旦添加了第三个国家/地区,代码就会崩溃 - 或者更确切地说,随着每个国家/地区的添加,代码会迫使您进入更深、更复杂的嵌套 IFs
      • @Rawrplus 我没有关注。我能够将示例扩展到 20 个国家/地区,并且该公式无需修改即可完美运行(除了为更大的数据集扩展范围之外)。
      • 抱歉,这实际上是我的一个错误,因为在我的示例数据中错误地计算了百分比排名(没有费心转录原始表格)。你是对的,公式是正确的! :)
      • 谢谢。该解决方案确实有效。但是不知何故,当我将它复制到另一列并将条件从 A 列更改为 E 时,我有一个错误。添加联合条件时也是如此,即 ($A$2:$A$21=A2)*($E$2:$E$21=E2)。功能之间似乎有些不匹配。
      • 如果您只是将条件列移动到E,它将是=PERCENTRANK(IF($E$2:$E$21=E2;$B$2:$B$21);B2)。至于联合条件,这对我有用:=PERCENTRANK(IF(($A$2:$A$21=A2)*($E$2:$E$21=E2);$B$2:$B$21);B2)
      猜你喜欢
      • 1970-01-01
      • 2018-01-16
      • 2014-09-06
      • 2016-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      相关资源
      最近更新 更多