Excel UDF 到表中的数据块的逆透视(融化、反向透视、展平、标准化)

2023-11-29

这个问题将寻求多种方法LET/LAMBDA VBA UDF and Power Query Function,因此不会有单一的正确答案,而是征集可供参考的方法。

Scott提出了一个问题here关于反转包含数据块而不是单个数据点的复杂表。基本思想如下表所示:

Jan Jan Jan Jan Feb Feb Feb Feb Mar Mar Mar Mar
State City Pressure Temp Humidity CO2 Pressure Temp Humidity CO2 Pressure Temp Humidity CO2
Georgia Atlanta 1 2 3 4 5 6 7 8 9 10 11 12
Massachusetts Boston 49 50 51 52 53 54 55 56 57 58 59 60
Texas Dallas 97 98 99 100 101 102 103 104 105 106 107 108
Louisiana Jonesboro 145 146 147 148 149 150 151 152 153 154 155 156
California San Francisco 193 194 195 196 197 198 199 200 201 202 203 204

每个城市的数据分为四列,包含压力、温度、湿度和 CO2(或 PTHC)。我们希望根据州和市的月份对 PTHC 值块进行逆透视。这是所需的输出:

State City month Pressure Temp Humidity CO2
Georgia Atlanta Jan 1 2 3 4
Georgia Atlanta Feb 5 6 7 8
Georgia Atlanta Mar 9 10 11 12
Massachusetts Boston Jan 49 50 51 52
Massachusetts Boston Feb 53 54 55 56
Massachusetts Boston Mar 57 58 59 60
Texas Dallas Jan 97 98 99 100
Texas Dallas Feb 101 102 103 104
Texas Dallas Mar 105 106 107 108
Louisiana Jonesboro Jan 145 146 147 148
Louisiana Jonesboro Feb 149 150 151 152
Louisiana Jonesboro Mar 153 154 155 156
California San Francisco Jan 193 194 195 196
California San Francisco Feb 197 198 199 200
California San Francisco Mar 201 202 203 204

行的顺序并不重要,只要它们完整即可 - 即输出可以按月份、城市、州排序……这并不重要。输出不需要是溢出的动态数组 - 即,在 Power Query 函数的情况下,显然不会。

可以假设 PTHC 块总是一致的,即

  • 它永远不会跳过字段值,例如PTHC PTC PTHC...
  • 它永远不会改变顺序,例如甲状腺激素治疗

月份始终以与块大小相同的组形式呈现(在本例中为 4,因此将有四个一月列、二月列等)。例如如果有7个月,则有7个PTHC块或28列数据。

However,月份的模式也可以交错,这样 月份将增加,并且 PTHC 块将被分组(即 PPP TTT HHH CCC) 像这样:

Jan Feb Mar Jan Feb Mar Jan Feb Mar Jan Feb Mar
State City Pressure Pressure Pressure Temp Temp Temp Humidity Humidity Humidity CO2 CO2 CO2

UDF 还必须在块内容纳多于或少于 4 个字段。 Months 和 PTHC 的使用只是说明,在本例中代表月份的属性将始终是单行(尽管多行方法将是一个有趣的问题 - 但这是一个新的单独的问题)。表示字段值 PTHC 的属性也将是单行。

我将根据 Scott 的问题提出一个 LET 函数,但是有 当然可以是更好的方法,VBA 和 Power Query 都有 他们自己的优势。目标是创建一个集合 工作方法。


LET/LAMBDA 方法

这需要Excel 365。公式为:

=LET( upValues, C3:N7,  upHdr, C2:N2,  upAttr, C1:N1,
      byBody, A3:B7,  byHdr, A2:B2,
      attrTitle, "month",

         upFields, UNIQUE( upHdr,1 ), blockSize, COUNTA( upFields ),
         byC, COLUMNS( byBody ), upC, COLUMNS( upValues ),
         dmxR, MIN( ROWS( upValues ), ROWS( byBody ) ),
         upCells, dmxR * upC/blockSize,
         tCSeq, SEQUENCE( 1, byC + 1 + blockSize ),  tRSeq, SEQUENCE( upCells + 1,, 0 ),  upSeq, SEQUENCE( upCells,, 0 ),
         hdr, IF( tCSeq <= byC,  INDEX( byHdr, , tCSeq ),
                 IF( tCSeq = byC + 1, attrTitle,
                     INDEX( upFields, 1, tCSeq - byC - 1 ) ) ),
         muxBody, INDEX( byBody, SEQUENCE( upCells, byC, 0 )/byC/upC*blockSize + 1, SEQUENCE( 1, byC ) ),
         muxAttr, INDEX( upAttr, MOD( SEQUENCE( upCells,, 0, blockSize ), upC ) + 1 ),
         muxValues, INDEX( upValues, SEQUENCE( upCells, blockSize, 0 )/upC+1, MOD(SEQUENCE( upCells, blockSize, 0 ),upC)+1),
         table, IF( tCSeq <= byC, muxBody,
                   IF( tCSeq = byC + 1, muxAttr,
                       INDEX( muxValues, upSeq + 1, tCSeq - byC - 1 ) ) ),
         IF( tRSeq = 0, hdr, INDEX( table, tRSeq, tCSeq) )  )

这需要 6 个变量:

  • upValues - 将在块中逆透视的数据
  • upHdr - 包含 PTHC 值的标题行
  • upAttr - 将取消透视的属性,即月份行
  • byBody - 将反转值的值主体,即 State 和 City 值
  • byHdr - byBody 的标头(标题“State”和“City”)
  • attrTitle - 将取消透视的属性的可选标题

在此图中可以更好地理解这些内容:

input table structure

为了更容易理解,这里给出了测试数据和显示的结果:

result

上面的输出也可以说明:

output parts

红色文本是用于构造结果的内部变量。

该公式由 5 个部分组成,如下所示:

parts

测量尺寸很明显 - 它只是参数化稍后将重复使用的变量。dmxR使用 upValues 或 byBody 行的 MIN 以防用户意外输入格式错误的值和 byBody,否则会导致无意义的输出。

构建序列创建三个用于索引输入和输出的序列:

  • tCSeq(表列序列)是按列调整大小的序列,最终输出表将具有 byBody + 属性(月份)+ 值(块大小)列。
  • tRSeq(表行序列)是一个按行序列,其大小适合最终输出表,该表将具有 dmxR*upC/blocksize + 1 (hdr) 行。
  • upSeq(unpivot 序列) 是一个按行序列,其大小适合最终输出表,该表将具有 dmxR*upC/blocksize 行(无标题)。

创建数组组件使用上面的维度和序列来构造输出表的各个部分。

  • hdr(header) 是带有标签(州和城市)、属性标题(月份)和字段名称 (PTHC) 的新标题。
  • muxBody(多路复用 byBody)是跨 dmxR 行多路复用的 byBody 的重复。
  • muxAttr(多路复用的 upAttr) 是跨 dmxR 行多路复用的 upAttr 的重复。
  • mux值(多路复用的 upValues) 是按块重复,将具有 dmxR*upC/blocksize 行。

最后两行stitch零件在一起。第一的,table缝针muxBody, muxAttr and mux值在逐列积分中使用tCSeq以及使用行式多路复用upSeq.

只是因为它在心理上更容易(并且更容易测试),我将行式集成分开(使用tRSeq) 的hdrtable在最后一行。

使用 IF 语句拼接的另一种方法是使用 IFERROR(INDEX ,它会强制出现错误,然后用表的下一部分替换错误,但这很难测试和调试,即使它只是按行或按列. 把row-wise和column-wise组合起来,就是一个cauchemar。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Excel UDF 到表中的数据块的逆透视(融化、反向透视、展平、标准化) 的相关文章

  • Spark引擎执行SQL时如何获取hive UDF中Spark的partitionId或taskContext?

    例如我们用Spark引擎执行下面的SQL 我们需要my udf row 返回 Spark 中的分区 id add jar hdfs dir udf udf jar create temporary function my udf as co
  • 如何使用 Excel VBA 根据货币标准格式化列中的数字?

    我想格式化一列的所有单元格 数据是一个数字 我想从左边添加一个小数 之后只保留两位数 然后根据货币标准对其进行格式化 例如 Data Output 10000 100 00 112233 1 122 33 123456789 1 234 5
  • VBA Excel 大数据操作需要很长时间

    我有两个Excel文件 第一个 Excel 文件包含 人员姓名 和 出席总天数 列 前任 PersonName TotalDays xyz abcd 另一个 Excel 文件包含人员姓名 日期和状态 出席 缺席 PersonName Dat
  • 如何从 500 个 .xls Excel 文件中的单元格中获取数据?

    我想问你如何从许多Excel中的几个确定的 并且总是相同的 单元格中获取数据 xls文件 即我有一个清单 xls文件位于一个文件夹中 每个文件内部都有相同的表 但具有不同的值 我想从以下位置获取数据A1 C2 E3从文件夹中的所有文件中提取
  • 通过将安全视图分配给角色并提供多种条件的过滤器,在 Snowflake 上实现行级安全性 (RLS)

    假设我们有一张水果详细信息表 Country Fruit USA Apple India Mango Italy Kiwi Australia Guava 我们有 3 个角色 即 region1 role region2 role and
  • 使用 Excel-VBA(MSXML2.XMLHTTP 对象)更新 SharePoint 列表

    基本信息 我需要从 Excel 更新 添加 编辑 SharePoint 列表 我能够做到这一点ListObject 但这不是我们要走向的方向 在阅读了所有谷歌可能性后 我想出了 也许我错了 使用的想法MSXML2 XMLHTTP对象来更新
  • 用户窗体上的类对象 TextBox 可用方法

    我注意到 当我为文本框创建类模块并在表单上使用它时 通过在表单 init 事件中通过 VBA 添加 Enter 或 Exit 方法都不可用 当然 如果我只是在表单中添加一个文本框 我可以让 DblClick 方法正常工作 因此我的类设置正确
  • 使用VBA复制垂直列并沿对角线粘贴

    我有一列数据 我们称之为 A 列 其中有 35 行数据 如何在此列上循环 然后将每个数据点粘贴到另一张工作表中 同时为每个循环循环增加列和行 换句话说 我寻求对角粘贴在第二张纸中 有没有一种简单的方法可以在 VBA 中执行此类操作 不要循环
  • VBA 激活 Internet Explorer 窗口

    我正在制作一个宏 用于打开 Internet Explorer 导航并登录网站 一切正常 但我需要将 IE 窗口放在前面并激活它 这样我就可以使用SendKeys在上面 我发现网站和视频在名为的命令上有不同的方法AppActivate我已经
  • MS Access 表单按钮,允许用户浏览/选择文件,然后将文件导入到表中

    在我的数据库中 我可以使用以下命令创建命令按钮导入文件 DoCmd TransferText acImportDelim 导入的原始数据 导入规范 导入的原始数据 D Users Denise Griffith Documents Grif
  • 将范围内的每个值乘以常数,但跳过空白单元格

    我需要一个简单快速的解决方案 用于将范围内的所有值乘以 VBA 代码中的数值 我知道这个解决方案 将整个范围乘以值 https stackoverflow com questions 18990541 multiply entire ran
  • VBA Shell 并等待退出代码

    我正在打包一个办公应用程序 VBA 它调用 C 控制台应用程序来执行应用程序 大型模拟程序 的一些繁重工作 我希望能够让 VBA 应用程序等待控制台应用程序完成并从控制台应用程序检索退出代码 我已经能够做到前者 但尚未能够从应用程序中检索退
  • 如何让VLOOKUP在VBA中选择到最低行?

    希望自动在单元格中插入 VLOOKUP 公式 录制宏时 我指示它使用相同的公式填充下面的列 效果很好 但是 当 VLOOKUP 搜索的表发生变化 更多或更少的行 时 就会出现问题 在记录时 VLOOKUP 下降到表中的最后一行 273 但是
  • 使用 ObjPtr(Me) 返回自定义类实例的名称?

    我明白那个ObjPtr http support microsoft com kb 199824将返回内存中对象的地址 并且它指向一个名为 IUNKNOWN 的结构 并且其中编码了某种接口定义以公开对象结构 但我不知道如何确定一个对象的接口
  • 我可以获取VBA代码中的注释文本吗

    可以说我有以下内容 Public Sub Information TEST End Sub 有没有办法得到 TEST 结果 不知何故通过VBA 例如 在 PHP 中 有一个获取注释的好方法 这里有什么想法吗 编辑 应该有办法 因为像 MZ
  • 标志状态的 VBA 替换

    根据文档 Outlook 中的 MailItem FlagStatus 属性是已弃用 https msdn microsoft com en us library microsoft office interop outlook maili
  • 获取当前 VBA 函数的名称

    对于错误处理代码 我想获取发生错误的当前 VBA 函数 或子函数 的名称 有谁知道如何做到这一点 编辑 谢谢大家 我曾希望存在一个未记录的技巧来自行确定函数 但这显然不存在 我想我会保留当前的代码 Option Compare Databa
  • 在 Excel 中使用 VBA 设置图像透明度

    有没有办法使用 VBA 脚本对图像应用一些透明度 我录制了一个 宏 但似乎没有录制艺术效果 我已经找到了如何制作形状 但没有找到图像 这需要几个步骤 将自选图形 如矩形 放置在工作表上 使用以下方法将您的实际图片嵌入矩形中 ShapeRan
  • 无法使用 VBA 代码从 Excel 连接到 Teradata - 无法通过网络访问 Teradata 服务器

    我一直在尝试使用 vba 代码从 Excel 连接到 Teradata 但收到以下错误 无法通过网络访问 Teradata Server 我已经能够从 Teradata SQL 助手成功连接 并且还成功 ping 通 Teradata 服务
  • 使用 split 函数到数组中会导致编译错误:无法分配给数组

    我正在尝试使用split 函数根据给定名称字符串中的空格拆分名称 当尝试编译我在下面编写的代码时 出现编译错误 无法分配给数组 我几乎从这里复制了微软的示例 https support microsoft com en us kb 2662

随机推荐

  • matlab如何比较数组

    我想比较两个字符串数组 我怎样才能影响以下值a b c d 当我尝试如下时 出现错误 a b c d getVal x gt this will gives a a b 0 c 10 d 我有 expected a 0 10 我怎样才能在
  • 录音机小部件不会停止录音

    我的应用程序涉及大量录音 因此我制作了一个小部件以便能够从主屏幕进行录音 我有一个 Recorder java 类 我在其中处理所有 MediaRecorder 调用 从活动中记录时 一切正常 从小部件录制时 它会录制 但不会在应该停止录制
  • Fortran 中的 if 或函数指针

    因为这在 Fortran 中很常见 所以我正在编写一个大规模并行的科学代码 在代码的开头 我阅读了配置文件 它告诉我要使用哪种类型的求解器 现在这意味着在子程序中 在主运行期间 我有 if solver eq 1 then call sol
  • Ansible async_status 任务 - 错误:ansible_job_id“未定义变量”

    我有一个 3 节点 ubuntu 20 04 lts kvm kubernetes 集群 kvm host 也是 ubuntu 20 04 lts 我在 kvm 主机上运行了 playbook 我有以下库存摘录 nodes hosts se
  • 如何使用 Java 在屏幕上移动 Windows 窗口?

    我一直在考虑制作一个带有 GUI 的窗口管理器 可能是用 Java 编写的 但是 我正在努力找出移动不属于我的程序的窗口的最佳方法 到目前为止 我似乎应该使用 JNI 与 Windows API 进行交互 但我还没有找到任何有用的示例 有谁
  • 如何以编程方式跳过摩卡测试?

    我有一个代码 其中某些测试在 CI 环境中总是会失败 我想根据环境条件禁用它们 如何在运行时执行期间以编程方式跳过摩卡测试 您可以通过在描述或它块前面放置一个x来跳过测试 或者放置一个 skip在它之后 xit should work fu
  • 如何确定应用程序的控制台窗口何时获得或失去焦点?

    有没有一种简单的方法可以做到这一点 或者至少检查控制台当前是否处于焦点状态 想象一下像游戏这样的东西 这里不是这种情况 但类比成立 如果它可以自动暂停 那将会很有用 我需要类似的东西 如果您感兴趣的窗口不是控制台窗口 则只需点击适当的焦点事
  • 为什么不使用 HashSet 类来实现 Enumerable.Distinct

    我需要访问的渐近时间和空间复杂度IEnumerable Distinct用大O表示法 所以我正在研究扩展方法的实现Enumerable Distinct我看到它是使用内部类实现的Set
  • JList 文本对齐

    我有一个JList我想显示两个值的项目 有没有办法让它显示字符串名称 然后用右对齐的字符串来显示值 看起来像这样 Title 120 Title2 135 是否可以将两个字符串传递给一个项目 并使第一个字符串显示在左侧 第二个字符串显示在右
  • Windows 窗体 - 从按钮类型的对象获取文本值

    我有一个名为Form1并在此表单中命名为面板panel1 我仅使用该面板将按钮放置在那里 以便我可以将它们分组并与我的其他按钮分开使用它们Form1 为了我的程序的目的 我需要处理从内部按钮进行的 每个按钮单击panel1 为此 我使用相同
  • java applet 小程序的替代品是什么?

    我正在开发一个 Web 应用程序 其中我们有一个客户端小程序应用程序 它将检查客户端计算机上是否安装了证书 但大家都知道 Mozilla 很快就会停止支持小程序 谁能建议做同样事情的替代选择是什么 Java 网络启动 The 其他答案已过期
  • 为什么 Chrome 在反复刷新使用 WebAssembly 的页面后最终会抛出“内存不足:wasm 内存”?

    我愿意相信刷新浏览器窗口或选项卡不会泄漏 不幸的是 当涉及 WebAssembly 时 情况似乎并非如此 我用 Rust 构建了一个 WebAssembly 箱 该包的编译大小约为 360 Kb 内容压缩之前 并且该包在 Firefox 甚
  • 这是将训练集投影到特征空间的正确方法吗? MATLAB

    我使用以下方法计算了 PCA function signals V pca2 data M N size data data reshape data M N 1 subtract off the mean for each dimensi
  • 将文本在 div 中垂直和水平居中

    我正在使用 bootstrap 并尝试创建一个高度和宽度与其宿主容器相同的 Cell 标题占该空间的 30 值占该空间的 70 该值有上限和下限 各占 20 为实际值留出 60 的空间 HTML div class container fl
  • Excel VBA退出Word文档

    我有一个宏 可以将 Excel 文档的选定单元格插入到 Word 模板中 复制整个 Word 文档 然后关闭文档而不保存 以保留某些关键字 但是 当它关闭 Word 文档时 它会打开一个空白的 Word 窗口 其中没有活动文档 并且每次运行
  • Django 模板和 MongoDB _id

    Variables and attributes may not begin with underscores value id 如何引用 idDjango 模板中从 MongoDB 获取的项目的数量 自定义模板过滤器有助于 from dj
  • jquery:.css 与附加到头部之间的速度差异?

    我们对内部应用程序有一些笨拙的解决方法 我想知道哪种 jQuery css 技术被认为更快 更高效 等等 技术A使用 css doc css margin top 90px checkouthelp css margin 50px 50px
  • 了解 Python 中的 for 循环

    我正在尝试创建一个for循环 我遇到了问题 我不明白这些循环是如何工作的 我认为问题是因为我正在使用for语法错误 据我了解 一个for循环应该看起来像 for w in words print w len w But 它究竟是如何运作的
  • 将 PHP Unix 时间戳转换为 Javascript 时间戳格式

    我将 php 中的 unix 时间戳抛出到 javascript 中 我注意到 PHP 和 Javascript 时间戳与纪元不同 秒与毫秒 我基本上所做的就是回显 php unix 时间 然后添加 3 个零 简单地将其乘以 1000 但我
  • Excel UDF 到表中的数据块的逆透视(融化、反向透视、展平、标准化)

    这个问题将寻求多种方法LET LAMBDA VBA UDF and Power Query Function 因此不会有单一的正确答案 而是征集可供参考的方法 Scott提出了一个问题here关于反转包含数据块而不是单个数据点的复杂表 基本