官方说明:
使用指定的组合程序函数将指定的列组合为一个新列。
Table.CombineColumns( table as table, sourceColumns as list, combiner as function, column as text) as table
解读:
合并列,在菜单栏里的"转换"和"添加列"选项卡中都有,添加列是将合并后的对象新增为一列,而点转换后合并的对象将不再存在。
先看添加列的方式,源数据如下图:
需要将每个人所有成绩写到一个格子里面用"-"符号连接,此时成绩的数据类型为text,于是可以直接点击添加列-合并列。
生成的公式为:
= Table.AddColumn(源, "合", each Text.Combine({[成绩1], [成绩2], [成绩3], [成绩4], [成绩5]}, "-"), type text)
这个很好理解,在此顺便讲一下如果源数据中成绩的类型为number,如果直接合并肯定会报错,需要先转换数据类型。
但是如果每一个都加上Text.From
那似乎就太长了,于是可以:
= Table.AddColumn(源,"合",each Text.Format("#[成绩1]-#[成绩2]-#[成绩3]-#[成绩4]-#[成绩5]",_))
使用Text.Format
能破除数据类型的门户之见。
以上是热身,今天主要讲的是转换合并的另一种形式:直接将对象进行合并的转换。
选中成绩列1按下SHIFT键再选择成绩5列,此时所有成绩列处于选择状态,在选区任意字段名上右击鼠标选择合并列。
此时弹出如上图所示,可以设置合并的连接符和对新的合并列命名。
= Table.CombineColumns(源,{"成绩1", "成绩2", "成绩3", "成绩4", "成绩5"},Combiner.CombineTextByDelimiter("-", QuoteStyle.None),"已合并")
这是他自动生成的代码,对此我表示不太满意,又要调一调:
= Table.CombineColumns(源,List.Skip(Table.ColumnNames(源)),each Text.Combine(_,"-"),"合")
分解看下参数:
第一参数为表;第二参数为需要合并的列名list;第三参数为具体的合并规则,参数类型为function;第四参数为新列的列名。
第二参数放哪列,转换后那一列就消失了,然后新增一个合并列。所以当第二参数为空列表的时候,那么源数据中就没有列会消失,反而会新增一列,此时作用相当于添加列:
= Table.CombineColumns(源,{},each Number.Random(),"合")
当第二参数是只有一个列对象的列表时你可以对该列进行变形扩展了:
= Table.CombineColumns(源,{"成绩1"},each _{0}&"分","合")
当有多个列对象作为第二参数是你就可以对这个列表下的数据进行列表的引用转换了:
= Table.CombineColumns(源,{"成绩1","成绩3"},each if Number.From(_{0})+Number.From(_{1})>160 then "合格" else "不合格","合")
有点意思吧,这里可以关联同行的不同列数据进行组合判断了。
再来看最关键的第三参数,虽然我们可以用Text.Combine
等函数自己合并,但同拆分有专门的Splitter类函数一样,合并也有专门的Combiner类函数。
相比于拆分,合并的函数较少只有5个,分别为Combiner.CombineTextByDelimiter
,Combiner.CombineTextByEachDelimiter
,Combiner.CombineTextByLengths
,Combiner.CombineTextByPositions
,Combiner.CombineTextByRanges
。
用法和拆分差不多,我就不单独开一篇去讲了。
首先看ByDelimiter,第一参数为text,也就是说所有的合并都按照这一个分隔符:
= Table.CombineColumns(源,List.Skip(Table.ColumnNames(源)),Combiner.CombineTextByDelimiter("-"),"合")
ByEachDelimiter第一参数为list,按指定顺序分配分隔符:
= Table.CombineColumns(源,List.Skip(Table.ColumnNames(源)),Combiner.CombineTextByEachDelimiter({"-","/"}),"合")
指定前两个分隔符,后面没有指定的默认无分隔符,合并就不像拆分可以选择靠左和靠右模式了。
拆分有两种形式:按分隔符与按字符数,同样合并也可以按连接符和字符位置进行合并。再看ByLengths:
= Table.CombineColumns(源,List.Skip(Table.ColumnNames(源)),Combiner.CombineTextByLengths({1,3,5}),"合")
虽然我们选择了5列,但是list中只给了3个元素,所以结果只对前3个合并。
以第一行为例,我们指定的字符数分别为1,3,5,所以依次取第一列中的1个字符也就是"9",第二列中的3个字符,不足位数的以空格补齐也就是"65 ",但注意补齐的空格只会加在中间而不会加在最后,因为要补齐的只是字符串之间的分隔符,第三列中的5个字符也就是"93"而不是"93 ",所以结果如上图所示。
ByLengths还有第二参数,为缺失位数的补齐值。
= Table.CombineColumns(源,List.Skip(Table.ColumnNames(源)),Combiner.CombineTextByLengths({1,3,5},"abcdefg"),"合")
这里给了一个7位数的字符串"abcdefg",如果没有该参数返回结果为"965 93",于是在第二参数对应的位置找到补齐值进行填充,结果为"965d93g"。
ByPositions和ByRanges都是差不多的意思,放两个案例大家自己慢慢体会吧:
= Table.CombineColumns(源,List.Skip(Table.ColumnNames(源)),Combiner.CombineTextByPositions({1,1,4},"abcdefg"),"合")
= Table.CombineColumns(源,List.Skip(Table.ColumnNames(源)),Combiner.CombineTextByRanges({{0,4},{4,3},{6,7}},"abcdefghi"),"合")
老师,Table.CombineColumns(源,List.Skip(Table.ColumnNames(源)),Combiner.CombineTextByRanges({{0,4},{4,3},{6,7}},"abcdefghi"),"合"),语法为:{{初始点1,长度1},{初始点2,长度2},...},初始点2和长度1、初始点1之间好像有联系,不能随便写,是这样吗?
感谢老师分享
我去,最后两个例子我看的最久