与ArrayFormula(Google表格)

时间:2017-11-30 11:04:00

标签: google-sheets array-formulas

我试图使用ArrayFormula在类别中找到反向排名。让我们假设一张包含

的表格
A    B         C
----------     -----
1    0.14      2
1    0.26      3
1    0.12      1
2    0.62      2
2    0.43      1
2    0.99      3

列A:B是输入数据,手动填充未知数量的有用行。 A是分类器类别,B是实际测量值。

C列是B值的反向排名,按A分组。可以为单个单元格计算,并复制到其余单元格,例如:

=1+COUNTIFS($B$2:$B,"<" & $B2, $A$2:$A, "=" & $A2)

但是,如果我尝试使用ArrayFormula:

=ARRAYFORMULA(1+COUNTIFS($B$2:$B,"<" & $B2:$B, $A$2:$A, "=" & $A2:$A))

它只计算一行,而不是填充所有数据范围。

使用COUNT(FILTER(...))而不是COUNTIFS的解决方案同样失败。

我想避免复制/粘贴公式,因为将来可能会增加行并且忘记再次复制可能会导致模糊的错误计算。因此,我很乐意为使用ArrayFormula的解决方案提供帮助。

感谢。

3 个答案:

答案 0 :(得分:1)

我没有看到Sheets中提供的数组公式的解决方案。这是一个带有自定义函数=inverserank(A:B)的数组解决方案。下面给出的函数应该在脚本编辑器(工具&gt;脚本编辑器)中输入。见Custom Functions in Google Sheets

function inverserank(arr) {
  arr = arr.filter(function(r) {
    return r[0] != "";
  });
  return arr.map(function(r1) {
    return arr.reduce(function(rank, r2) {
      return rank += (r2[0] == r1[0] && r2[1] < r1[1]);
    }, 1);
  });
}

说明:A:B中的双值数组是

  1. 过滤,以消除空行(其中A条目为空)
  2. 通过每行r1然后
  3. 的函数映射
  4. 减少数组,仅在每行(r2)具有相同类别且小于r1的值时对其进行计数。它返回计数加1,因此最小元素得到等级1.
  5. 没有实施打破平局:例如,如果有两个最小的元素,它们都获得等级1,并且没有等级2;下一个最小的元素获得等级3.

答案 1 :(得分:0)

这确实给出了答案,但我不得不经历一个相当复杂的操作来找到它:

=ArrayFormula(iferror(VLOOKUP(row(A2:A),{sort({row(A2:A),A2:B},2,1,3,1),row(A2:A)},4,false)-rank(A2:A,A2:A,true),""))

![enter image description here

所以

  1. 使用行号对cols A和B进行排序。
  2. 使用查找来查找现在排序的行号的位置:它们的位置给出原始数据中该行的等级加1(3,4,2,6,5,7)。
  3. 返回新的行号。
  4. 减去仅通过A列(1,1,1,4,4,4)排名获得的排名,以获得每个组中的排名。
  5. 在分类器(col A)是整数并且测量值(col B)是分数的特定情况下,您可以添加两列并使用等级:

    =ArrayFormula(iferror(rank(A2:A+B2:B,if(A2:A<>"",A2:A+B2:B),true)-rank(A2:A,A2:A,true)+1,""))
    

答案 2 :(得分:0)

我的数组公式的版本,它在列A包含文本时起作用:

=ARRAYFORMULA(RANK(ARRAY_CONSTRAIN(VLOOKUP(A1:A,{UNIQUE(FILTER(A1:A,A1:A<>"")),ROW(INDIRECT("a1:a"&COUNTUNIQUE(A1:A)))},2,)*1000+B1:B,COUNTA(A1:A),1),ARRAY_CONSTRAIN(VLOOKUP(A1:A,{UNIQUE(FILTER(A1:A,A1:A<>"")),ROW(INDIRECT("a1:a"&COUNTUNIQUE(A1:A)))},2,)*1000+B1:B,COUNTA(A1:A),1),1) - COUNTIF(A1:A,"<"&OFFSET(A1,,,COUNTA(A1:A))))