ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 3222|回复: 3

[求助] Power Query根据其他列数值替换

[复制链接]

TA的精华主题

TA的得分主题

发表于 2019-7-23 14:31 | 显示全部楼层 |阅读模式
求助一个问题,我想根据A列的数值来决定是否替换B列的值,例如
A B
Y 12
N 32

在别的地方看到的方法是如果b列为12,则替换为A列的值
= Table.ReplaceValue(源,12,each [A],Replacer.ReplaceValue,{"B"})
此方法可行
现在我希望如果A列为Y,则把B列替换为100,但是把二三参数颠倒过来就是没有效果的,比如
= Table.ReplaceValue(源,each [A]="Y",100,Replacer.ReplaceValue,{"B"})


想不通其中的原理,请大神赐教,或者有其他的解决方法~谢谢
(用条件列加一列再删除的方法我是知道的,我只想挖掘一个一步到位的方法。)




TA的精华主题

TA的得分主题

发表于 2019-7-23 17:03 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-7-24 16:59 | 显示全部楼层
万分感谢,的确是可用的,稍微多走一步就可以解决的,套路知道的还不够深,哈哈
就是还想不通为什么我原来的想法却无法实现~~

TA的精华主题

TA的得分主题

发表于 2021-10-4 00:57 | 显示全部楼层
lifibosh 发表于 2019-7-24 16:59
万分感谢,的确是可用的,稍微多走一步就可以解决的,套路知道的还不够深,哈哈
就是还想不通为什么我原来 ...

回复一个两年前的问题,不知道楼主是否能看到。

实际上Table.ReplaceValue函数的标准格式是要求比较明确的
=Table.ReplaceValue(table,old value,new value,Replacer函数, {"要查找的column名"(这里可以多列,需要逗号分开用大括弧整体括在外面作为一个list}) )

所以原来那句= Table.ReplaceValue(源,12,each [A],Replacer.ReplaceValue,{"B"})
就是:在B列中,查所有oldvalue=12的,把它替换为 当前行(each 上下文就变成B列的逐行)中的列A内的内容(newvalue)。

而你想实现的【如果A列为Y,则把B列替换为100= Table.ReplaceValue(源,each [A]="Y",100,Replacer.ReplaceValue,{"B"})为什么没有效果呢?


这是因为如果按照你的要求,PQ会理解为,你要在B列中,查找的oldvalue是 each [A]="Y' 而不是 "Y",也不是去查找A列是否等于Y。
这句有点绕,但实际上你理解为它要先去判断 [A]="Y"这个表达式的值,而这是一个逻辑判断,值就只有TRUE or FALSE。
然而在B列中并没有这样两个逻辑值的存在,所以找不到这个oldValue,自然就无法触发替换动作了。


这个假设可以通过构造一个C列,来验证:=Table.AddColumn(源,"C", each if [A]="Y" then true  else false, type logical )
这时候表格如下
A B C
Y 12 TRUE
N 32 FALSE


这时候再加一句:= Table.ReplaceValue(已添加自定义,each [A]="Y",100,(x,y,z)=>if y then z else y,{"C"})
就会发现C的第一行的TRUE被成功替换成100了。第二行则保持不动,因为FALSE不符合 A=100的条件判断。

A B C
Y 12 100
N 32 FALSE


需要注意的是,这里Replacer.ReplaceValue函数被我用自定义三参函数 (x,y,z) 替换。
所有PQ函数里的子函数 如果有特定的参数要求的时候,都可以被同样的参数数量的自定义函数替换。(可以研究一下splitter/combiner/replacer这几个系列)

当你把(x,y,z)改回Replacer.ReplaceValue的时候,就会发现 C列下的100和FALSE都被替换成了100。答案也是很显然的,因为在原版replacer函数这里,是直接对x这个值里去查找y并且替换成z。如果我们构造的C列本身是TRUE和FALSE两行的值,而[A]="Y"的判断在第一行也就是TRUE,第二行也就是FALSE。所以就等于 if x=y then z,所以两行都会被替换成100。

总结:
1. 错误写法:= Table.ReplaceValue(源,each [A]="Y",100,Replacer.ReplaceValue,{"B"})
2. 正确写法:= Table.ReplaceValue(,each [A]="Y",100,(x,y,z)=>if y then z else x,{"B"})

直接使用Replacer函数时,y在前面的写法会输出逻辑值true/false,而B列中并不存在,所以查不到,不会触发替换。
需要改成自定义三参,使用条件判断 if y (=true or false)来进一步指定B列(x)被赋值为z(100),或者不动,还是B列原值。


评分

2

查看全部评分

您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-16 03:21 , Processed in 0.035441 second(s), 16 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表