Google sheets 如何列出一个范围内最常用的文本值?

Google sheets 如何列出一个范围内最常用的文本值?,google-sheets,Google Sheets,我是一个中级excel用户,试图解决一个让我有点不知所措的问题。基本上,我正在使用一个电子表格,其中包含许多与客户帐户相关联的订单,并且最多有5个与之相关联的元数据“标记”。我想使用该客户帐户按顺序提取5个最常见的元数据标记 我试图使用建议的公式: 但我不知道如何a)使用客户帐户作为计算范围内文本值的先决条件。b) 如何避免Match forumula只想处理一列数据,以及c)如何从该范围读取第二、第三、第四和第五个最常见的值 我格式化这些数据的方式不是一成不变的。我怀疑我组织这些信息的方式

我是一个中级excel用户,试图解决一个让我有点不知所措的问题。基本上,我正在使用一个电子表格,其中包含许多与客户帐户相关联的订单,并且最多有5个与之相关联的元数据“标记”。我想使用该客户帐户按顺序提取5个最常见的元数据标记

我试图使用建议的公式:

但我不知道如何a)使用客户帐户作为计算范围内文本值的先决条件。b) 如何避免Match forumula只想处理一列数据,以及c)如何从该范围读取第二、第三、第四和第五个最常见的值


我格式化这些数据的方式不是一成不变的。我怀疑我组织这些信息的方式阻碍了我使用更简单的解决方案,因此,任何关于重新思考我的组织的建议都将与关于如何创建公式来实现这一点的见解一样有用。

使用内置函数实现这种频率分析可能是一项令人沮丧的工作。由于您使用的是Google Sheets,因此可以利用使用JavaScript编写并放入绑定到工作表的脚本(工具>脚本编辑器)中的

下面是我为此编写的函数。在工作表中输入类似于
=tagfrequency(A2:G100)
的内容将产生所需的输出:

+----------------+-----------------+-----+-----+-----+-----+
| Account Number | Most Common Tag | 2nd | 3rd | 4th | 5th |
| 5043           | D               | A   | C   | B   | N/A |
| 4350           | B               | D   | C   | N/A | N/A |
| 1204           | B               | A   | D   | N/A | N/A |
+----------------+-----------------+-----+-----+-----+-----+
自定义函数
功能标签频率(arr){
var dict={};//存储标记计数的对象
对于(变量i=0;itags[b]?-1:(a>b1:-1));
}));//按标记计数排序,然后按标记名称排序
while(行长<6){
row.push('N/A');//如果需要,添加N/A
}
output.push(行);//将行添加到输出
}
返回输出;
}

您还可以获得以下报告:

Account Number     Tag    count 
          1204      B         2
          1204      A         1
          1204      D         1
          4350      B         3
          4350      D         2
          4350      C         1
          5043      D         5
          5043      A         4
          5043      C         3
          5043      B         1
根据公式:

    =QUERY(
     {TRANSPOSE(SPLIT(JOIN("",ArrayFormula(REPT(FILTER(A2:A,A2:A<>"")&",",5))),",")),
      TRANSPOSE(SPLIT(ArrayFormula(CONCATENATE(FILTER(C2:G,A2:A<>"")&" ,")),",")),
      TRANSPOSE(SPLIT(rept("1,",counta(A2:A)*5),","))
     },
   "select Col1, Col2, Count(Col3) where Col2 <>' ' group by Col1, Col2
    order by Col1, Count(Col3) desc label Col1 'Account Number', Col2 'Tag'")
=查询(
{转置(拆分(联接(“,数组公式(报告(过滤器(A2:A,A2:A)”)&“,”,5)),“,”),
转置(拆分(数组形式)(串联(过滤器(C2:G,A2:A“”)和“,”),“,”),
转置(拆分(报告(“1”,计数A(A2:A)*5),“,”)
},
选择Col1,Col2,Count(Col3),其中Col2“”按Col1,Col2分组
按Col1排序,计数(Col3)描述标签Col1'账号',Col2'标签')

公式将计算任何标记的出现次数。

ARRAYFORMULA()
不是Excel,而是Google sheets。另外,在原始文章中以文本形式发布数据,因此我们无需重新键入表格来测试公式。如果你不能正确格式化,就发布它,有人会帮你格式化。谢谢,用文本更新。是的,我在谷歌工作。我不确定我是否应该提到这一点。问题是你的数据设置不好。元数据应该在一列中,而不是多列中,特别是因为每个帐号已经有多行。有了像你现在这样的数据设置,得到你想要的结果会更加复杂,是的,我想。只要最终结果仍然可以按频率顺序列出各个标记,而不是将它们放在一列中听起来很好,如果这能让事情更简单的话。非常感谢。玩这个游戏,我认为它会工作得很好。现在,在实践中,这些数据的布局方式是在帐户和标记之间有多个与每个订单相关联的额外信息列。有没有办法修改此函数以跳过该信息?在这种情况下,账户和标签之间还有13列额外的信息,我不想被公式解读为“标签”。您应该相应地修改循环
j
。现在它是(var j=2;j,意思是它以2开头。因此,j=0是帐号,j=1是订单号(跳过),标记以j=2开头。如果您还有13列要跳过,j将以15而不是2开头。谢谢,Max!我真的很感激。由于此公式的目标基本上是创建帐户偏好的摘要,因此此报告并不理想。
+----------------+-----------------+-----+-----+-----+-----+
| Account Number | Most Common Tag | 2nd | 3rd | 4th | 5th |
| 5043           | D               | A   | C   | B   | N/A |
| 4350           | B               | D   | C   | N/A | N/A |
| 1204           | B               | A   | D   | N/A | N/A |
+----------------+-----------------+-----+-----+-----+-----+
function tagFrequency(arr) {
  var dict = {};                   // the object in which to store tag counts
  for (var i = 0; i < arr.length; i++) {
    var acct = arr[i][0];
    if (acct == '') {
      continue;                    // ignore empty rows
    }
    if (!dict[acct]) {
      dict[acct] = {};             // new account number
    }
    for (var j = 2; j < arr[i].length; j++) {
      var tag = arr[i][j];
      if (tag) {
        if (!dict[acct][tag]) {
          dict[acct][tag] = 0;      // new tag 
        }
        dict[acct][tag]++;          // increment tag count
      }
    }
  }
                    //  end of recording, begin sorting and output 
  var output = [['Account Number', 'Most Common Tag', '2nd', '3rd', '4th', '5th']];
  for (acct in dict) {
    var tags = dict[acct];
    var row = [acct].concat(Object.keys(tags).sort(function (a,b) {
      return (tags[a] < tags[b] ? 1 : (tags[a] > tags[b] ? -1 : (a > b ? 1 : -1)));
    }));                        // sorting by tag count, then tag name
    while (row.length < 6) {
      row.push('N/A');          // add N/A if needed 
    }
    output.push(row);           // add row to output 
  }
  return output;  
}
Account Number     Tag    count 
          1204      B         2
          1204      A         1
          1204      D         1
          4350      B         3
          4350      D         2
          4350      C         1
          5043      D         5
          5043      A         4
          5043      C         3
          5043      B         1
    =QUERY(
     {TRANSPOSE(SPLIT(JOIN("",ArrayFormula(REPT(FILTER(A2:A,A2:A<>"")&",",5))),",")),
      TRANSPOSE(SPLIT(ArrayFormula(CONCATENATE(FILTER(C2:G,A2:A<>"")&" ,")),",")),
      TRANSPOSE(SPLIT(rept("1,",counta(A2:A)*5),","))
     },
   "select Col1, Col2, Count(Col3) where Col2 <>' ' group by Col1, Col2
    order by Col1, Count(Col3) desc label Col1 'Account Number', Col2 'Tag'")