有没有一种方法可以使用与 google 工作表中的行和列相同的字段来计算列之间的唯一出现次数?

Is there a way to use same field as rows and columns in google sheets to count unique occurrence between columns?

希望转换

Task id John Jan Juliet
1 1 1 0
2 1 0 1
3 0 1 1
4 0 0 1
5 0 1 1
6 1 1 0
7 0 1 0
8 1 0 0
9 0 1 1
10 1 1 0

John Jan Juliet
John 3 1
Jan 3 3
Juliet 1 3

我已经在你的样本传播中设置了一个新的sheet(“Erik Help”)sheet。

在 B1:

=SORT(FILTER(Sheet1!B1:1,Sheet1!B1:1<>""))

这只是用您的姓名列表填充顶行,按字母顺序排序。

在 A2 中:

=TRANSPOSE(SORT(FILTER(Sheet1!B1:1,Sheet1!B1:1<>"")))

这会用与上面相同的姓名列表垂直填充 A2。

在 B2 中是网格的主要公式(然后上下拖动):

=ArrayFormula(IF( ($A2="") + (B="") + ($A2=B),, SUM(MMULT(IF((FILTER(Sheet1!$B:$L,Sheet1!$A:$A<>"")=1) * (Sheet1!$B:$L=$A2),1,0), SEQUENCE(COLUMNS(Sheet1!$B:$L),1,1,0)) * MMULT(IF((FILTER(Sheet1!$B:$L,Sheet1!$A:$A<>"")=1) * (Sheet1!$B:$L=B),1,0), SEQUENCE(COLUMNS(Sheet1!$B:$L),1,1,0)))))

第一个 ( ) + ( ) + ( ) 测试三个 OR 条件。如果有任何一个为真,则该单元格将留空。这就是允许公式一直向右和向下拖动而不会抛出错误的原因,本质上,“等待”来自它可以处理的前两个公式的新数据。

公式的其余部分过于复杂,无法保证完整解释(例如,如何 MMULT 详细工作),这是一个志愿者-运行 站点。 (写公式所花的时间比我通常花在这个论坛或其他论坛上的时间还要多。)但这是要点。

两个网格——每个网格由一个 MMULT(矩阵乘法)形成——被求和。第一个 MMULT 将生成一个与 Sheet1 网格大小相同的网格,仅当满足 两个条件时才填充 1 :该插槽中已经有一个 1 并且上面的名称匹配“Erik 帮助”网格中右侧的名称。否则,该槽的结果为零。第二个 MMULT 基于相同的条件形成相同大小的网格,只是这次它得到一个 1 只有当 已经有一个 1 并且上面的名称与“中单元格上面的名称相匹配”埃里克帮忙。”这两个格子相乘,如果乘积是 1,我们就知道两个名字都有一个 1。求和后,我们将获得这两个名称的共享项目数。

随着这个公式被拖动,单元格引用 锁定美元符号将调整,以便两个不同的名称将由两个 MMULT 网格进行比较。

因为这个解决方案需要将数组与数组与数组进行比较,我目前看不到进一步的数组解决方案是如何可能的,因此需要拖动公式。也就是说,这些公式中的每一个都已经挤满了数组处理。

同样,该公式当前一直拖到 Z 列并向下拖到第 200 行。但是,它最多只引用 L 列(就您当前的名称列表而言)。如果您的实际应用程序有更多名称,因此会沿用 L 列,一次更改所有公式的最简单方法是:

  1. 转到“Erik 帮助”sheet(当然,您可以根据需要重命名)。

  2. 按 Ctrl-H 打开 Find/Replace 对话框。

  3. 在 FIND 字段中输入 $L,在 REPLACE 字段中输入 $?(其中 ? 将是您希望结果扩展到的新列,例如 $M$P,等等)

  4. 从“搜索”下拉菜单中选择“这个 sheet”。

  5. 选中“也在公式内搜索”旁边的框。

  6. 单击“全部替换”按钮。

如果数据集再次收缩或增长,执行相同的步骤,只需将旧的最远列引用更改为新的最远列引用。

这是一种 super-simple 的实现方式,当公式通过相对寻址上下移动时,它只会更改在 countifs 中选择的一对列:

=countifs(index($B:$D,0,row(A1)),1,index($B:$D,0,column(A1)),1)

被拉下来。

尝试更通用的解决方案。

问题已标记 pivot-table。虽然 pivot table 方法看起来很有用,但数据的格式完全错误,无法实现它。任务是将数据从 1 和 0 转换为列号,因此

1 1 0 => 1 2

1 0 1 => 1 3

1 1 1 => 1 2, 1 3 and 2 3.

这可以通过如下生成数字对并在原始数据中执行查找来实现:

1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
3 3

生成这些序列的公式是

=ArrayFormula(quotient(mod(sequence(90,1,0),9),3)+1)

=ArrayFormula(mod(sequence(90,1,0),3)+1)

(9因为每行数据有3X3对,90因为有10行数据)。

下面为每行数据生成一个查找

=ArrayFormula(quotient(sequence(90,1,0),9)+1)

将所有这些放在一起并将其包装在数据透视查询中给出

=ArrayFormula(query({vlookup(quotient(sequence(90,1,0),9)+2,{row(B2:D),B2:D},quotient(mod(sequence(90,1,0),9),3)+2,0)*(quotient(mod(sequence(90,1,0),9),3)+1),
vlookup(quotient(sequence(90,1,0),9)+2,{row(B2:D),B2:D},mod(sequence(90,1,0),3)+2,0)*(mod(sequence(90,1,0),3)+1)},
"select count(Col1) where Col1<>0 and Col2<>0 group by Col1 pivot Col2"))

公式可以推广到不同的行数和列数。