Forum Discussion
Power Query - Table.ReplaceValue - Behavior ?
Hi,
My question is very basic and is about the behavior of Table.ReplaceValue. Below a table in PWQ
| income | kindhome | teenhome |
5011 | 0 | 0 |
| 4600 | 1 | 1 |
| 7000 | 0 | 0 |
| 2600 | 1 | 1 |
| 5800 | 1 | 0 |
| 6300 | 0 | 1 |
| 5567 | 0 | 1 |
| 3333 | 1 | 1 |
I d'ont understant the two different results between
= Table.ReplaceValue( #"Typage", each [kidhome], each 2,
Replacer.ReplaceValue,
{"kidhome", "teenhome"})
and
= Table.ReplaceValue( #"Typage", each [kidhome], each 2,
(curval,oldval, newval)=> newval,
{"kidhome", "teenhome"})
Subsidiary question
Table.ReplaceValue( table as table, oldValue as any, newValue as any, replacer as function, columnsToSearch as list, ) as table
Why a personal replacer function is declared why 3 parameters mandatory (x,y,z) => ?
How each parameter is well associated with the 3 first parameters of Table.ReplaceValue ?
Thanks by advance for your help ?
Sur les points 1 et 3
quand vous ajoutez une colonne à une table, vous ne vous demandez pas ce que veut dire le [xxxx]
exemple, si vous créez une nouvelle colonne avec les 2 derniers caractères d'une autre colonne
= Table.AddColumn(Source, "Column2", each Text.End([Column1], 2), type text)
le [Column1] désigne le texte contenu dans le champ intitulé "Column1" de votre ligne en cours
cela vous semble naturel !
vous pourriez également écrire :
= Table.AddColumn(Source, "Column2", (_) => Text.End(_[Column1], 2), type text)
ici j'ai mis un _ mais vous auriez pu mettre un x ou informer
cette syntaxe est valable
= Table.AddColumn(Source, "Column2", (informer) => Text.End(informer[Column1], 2), type text)
il est implicite que "informer" est l'enregistrement en cours (de l'étape "source")
La fonction Table.ReplaceValue est plus complexe car la fonction du 4e argument utilise les 3 arguments précédents pour elle-même. quelque soit les noms qu'on leur donne (x,y,z) ou (a,b,c) ou (informer1,informer2,informer3)
= Table.ReplaceValue(Source, Argument2, Argument3, (informer1,informer2,informer3)=>informer2, {"Column1"}ici on remplacera la column1 par le valeur du 2e argument
ce peut être du texte, un nombre, une liste... lié à la ligne en cours si on a un each...
mais également une valeur d'une autre requête
un exemple tiré par les cheveux pour bien comprendre,
let
Source = Table.FromColumns({{1..3}},{"Column1"}),
Replace = Table.ReplaceValue(Source, Source[Column1], (toto)=> Source , (a,b,c)=>a, {"Column1"})
in
Replacene changera rien à la column1, on prend la valeur du premier argument (donc la column1) et on le remet.
let
Source = Table.FromColumns({{1..3}},{"Column1"}),
Replace = Table.ReplaceValue(Source, Source[Column1], (toto)=> Source , (a,b,c)=>b, {"Column1"})
in
Replaceon n'a pas de each, on n'est donc pas dans la ligne en cours, on prendre la colonne "Column1" de la table "Source" c'est à dire la colonne elle-même (en entier !)
on aura donc une liste {1..3} dans chaque cellule.
enfin,
let
Source = Table.FromColumns({{1..3}},{"Column1"}),
Replace = Table.ReplaceValue(Source, Source[Column1], (toto)=> Source , (a,b,c)=>c, {"Column1"})
in
Replaceici la fonction renvoie c, le 3eme argument que j'ai volontairement écrit (toto)=> (toto ou _ ou each, c'est la même chose, c'est la ligne en cours
sauf que là, je ne renvoie pas un champ spécifique de la ligne avec des [ ] mais Source, donc l'étape précédente.
Dans toutes les cellules j'aurais donc la table Source avec sa seule colonne de trois valeurs, 1, 2, 3.
Quant au point 2, Power Query ne génère pas d'erreur lorsqu'il n'y a pas assez d'argument, mais les modifications ne sont pas effectuées
Si par exemple j'écris := Table.ReplaceValue(Source, each null, each null , Date.Day, {"Column1"})Date.Day est une fonction avec un seul argument, je n'ai aucune erreur, mais la fonction ne remplace rien.
= Table.ReplaceValue(Source, each null, each null , List.Accumulate, {"Column1"})pas d'erreur non plus avec List.Alternate qui demande pourtant 3 arguments. la fonction renvoie un erreur, il ne se passe rien. peut-être un bug de Power Query ?
Est-ce plus clair ?
Stéphane
25 Replies
- AlienSxSuper User
informer lets start from your last questions:
# 3 mandatory parameters for custom replacer: it's because Table.ReplaceValue passes all 3 to this function.
# assiciations: look at any standard PQ replacer function definition:
Replacer.ReplaceValue(value as any, old as any, new as any) as anyArguments' values are passed in the same order. So that
value : current value in one of columnsToSearch
old: oldValue in Table.ReplaceValue
new: newValue in Table.ReplaceValue
Keeping the above in mind try to imagine what's going on in your use cases: column by column, row by row...
- informerHelper I
Thanks for your help
The 4th parameter is a function
I don't understant the 2nd exemple because it's a personal function and Replacer.ReplaceValue is never called
(curval,oldval, newval)=> newval,In the example below, Replacer.ReplaceValue is not called
= Table.ReplaceValue( Source, each [Acronyme], null, (x,y,z) => List.Accumulate( List.Reverse(Text.PositionOf(x, y, Occurrence.All, Comparer.OrdinalIgnoreCase)), x, (s,c)=>Text.RemoveRange(s, c, Text.Length(y))), {"Nom", "Volume", "Circulating Supply"})In the Table.ReplaceValue, nothing is precised about parameters to pass in
replacer as function,
I'm sure I'm missing something about construction of a personal function !!!
- AlienSxSuper User
what's so special about Replacer.ReplaceValue? It's one of many other functions in M. You may use any other custom function with the same list of agruments. All you need to now is that Table.ReplaceValue passes exactly 3 values into it's 4th argument (the function we are talking about). By "passes" I mean that Table.ReplaceValue calls that function like we call any other function in M. Back to your examples:
1. The one with Replacer.ReplaceValue: full syntax of this "replacer" is
Replacer.ReplaceValue(value as any, old as any, new as any) as anyand basically it compares value with old and if value = old then it replaces value with new. Your "old" argument always has a value of kidhome field. And when Table.ReplaceValue works with "kidhome" column then value is always equal to old. That's why kidhome column = 2 (as you defined new) after transformation.
When working with teenhome field, it's value will be replaced by 2 only when [teenhome] = [kidhome] (or when value = old). That's why replacements are made in rows 1 through 4 and 8.
2. The one with custom function: here your custom function always returns a value of new with is 2 in your case - without regard of any other values in any other column. That's why both column's values got replaced with 2.
Table.ReplaceValue is not easy to understand and I feel your frustration. Good luck!
- ZhangKunSuper User
This is an interesting question. It seems that you are very interested in the second example.
Before explaining this question, you should know that if a table function needs a function as a parameter, it usually passes the parameters in order, which I call implicit parameter passing. For example, the third parameter of the Table.AddColumn function needs to specify a function. During the execution of the Table.AddColumn function, it passes the table row (a record value) as a parameter to the third parameter (a function), and then calculates a result as the value of the new column.
The same is true for the Table.ReplaceValue function, which implicitly passes the value of each row of the column specified in the fifth parameter, the second parameter, and the third parameter to the fourth parameter (a function).The fourth argument (a function) computes a result based on the three provided arguments, which is then used as the new value to replace the original value.
In the second example, your result is a fixed value (newval), so it will always replace the original value in the table with newval(it corresponds to the third parameter).
Here are some examples I learned before, maybe they can help you.
Table.ReplaceValue( #table({"A", "B"}, {{1, 2}, {11, 11}, {101, 102}}), 11, 666, Replacer.ReplaceValue, {"A"} ) Table.ReplaceValue( #table({"A", "B"}, {{1, "take"}, {11, "make"}, {111, "like"}}), "ak", "****", Replacer.ReplaceText, {"B"} ) Table.ReplaceValue( #table({"A", "B"}, {{1, 2}, {11, 11}, {101, 102}}), 888, 666, (x, y, z) => if x = 11 then y else z, {"A"} ) Table.ReplaceValue( #table({"A", "B"}, {{1, 2}, {11, 11}, {101, 102}}), null, null, (x, y, z) => if x = 11 then x * 100 else x / 100, {"A"} ) Table.ReplaceValue( #table({"A", "B"}, {{1, 2}, {11, 11}, {101, 102}}), each [B], 666, (x, y, z) => if y = 102 then 777 else x, {"A"} )- AntrikshSharmaCommunity Champion
ZhangKun Greate examples! For the last example I believe you wanted to write:
(x, y, z) => if y = 102 then z else xFor those who might find x, y, z difficult to understand at first.
Table.ReplaceValue ( #table ( { "A", "B" }, { { 1, 2 }, { 11, 11 }, { 101, 102 } } ), each [B], 666, ( CurrentValue, OldValue, NewValue ) => if OldValue = 102 then NewValue else CurrentValue, { "A" } )- ZhangKunSuper User
This is an example from a little back ago, and I was trying to say that the second and third parameters of Table.ReplaceValue do not necessarily have to be used in the fourth parameter.
- lbendlinSuper User
Your second example has too many parameters. If you specify the replacer function then the
each [kidhome], each 2part is ignored.
- dufoq3Community Champion
Hi informer, check Rick's article.
- AnonymousNot applicable
Hi informer,
Thanks for reaching out to the Microsoft fabric community forum.
It looks like you are trying to use "Table.ReplaceValue" function but in two different ways. As ronrsnfld, lbendlin, slorin and ZhangKun provided with responses, were you able to solve your issue? If your issue is solved then kindly mark the helpful response as solution and if you still have queries left then kindly mention your primary queries.
I would also take a moment to thank ZhangKun, lbendlin, AntrikshSharma and AlienSx, for actively participating in the community forum and for the solutions you’ve been sharing in the community forum. Your contributions make a real difference.
If I misunderstand your needs or you still have problems on it, please feel free to let us know.
Best Regards,
Hammad.
Community Support TeamIf this post helps then please mark it as a solution, so that other members find it more quickly.
Thank you.