Kdb 如何在q中将表格从宽转长
我正在尝试编写一个函数,将我的表从宽格式转换为长格式。 所以我有一些关于这方面的东西:Kdb 如何在q中将表格从宽转长,kdb,Kdb,我正在尝试编写一个函数,将我的表从宽格式转换为长格式。 所以我有一些关于这方面的东西: tblwide:([]k1:`a`a`b`b`c`c;xx:1 2 3 4 5 6;yy:11 12 13 14 15 16); wide2long:{[lhscolnames;rhscolname;varcolname;valuecolname] ?[tblwide;enlist(~:;(^:;rhscolname));0b;((lhscolnames),varcolname,valuecolname)!(
tblwide:([]k1:`a`a`b`b`c`c;xx:1 2 3 4 5 6;yy:11 12 13 14 15 16);
wide2long:{[lhscolnames;rhscolname;varcolname;valuecolname] ?[tblwide;enlist(~:;(^:;rhscolname));0b;((lhscolnames),varcolname,valuecolname)!(eval lhscolnames;enlist rhscolname;rhscolname)] };
tbllong:raze wide2long[enlist `k1;;`index;`val] each (cols tblwide) except `k1;
这似乎是可行的。现在,当我想要有几个不以轴为中心的列时,调整代码:
tblwide:([]k1:`a`a`b`b`c`c;k2:`t`u`t`u`t`u;xx:1 2 3 4 5 6;yy:11 12 13 14 15 16)
wide2long:{[lhscolnames;rhscolname;varcolname;valuecolname] ?[tblwide;enlist(~:;(^:;rhscolname));0b;((lhscolnames),varcolname,valuecolname)!(eval lhscolnames;enlist rhscolname;rhscolname)] };
tbllong:raze wide2long[`k1`k2;;`index;`val] each (cols tblwide) except `k1`k2;
然后它就不起作用了。似乎q不喜欢eval
如果我方没有错误,预期结果是:
expected:([] k1:`a`a`b`b`c`c`a`a`b`b`c`c; k2:`t`u`t`u`t`u`t`u`t`u`t`u ; index:`xx`xx`xx`xx`xx`xx`yy`yy`yy`yy`yy`yy;val:1 2 3 4 5 6 11 12 13 14 15 16)
订单并不重要,我可以以后再重新订购
我完全愿意接受其他更简单/更快的解决方案,但仍然很乐意了解如何使用
eval
解决此问题。我认为您根本不需要eval
。这样的方法应该适用于两种情况:
wide2long:{[lhscolnames;rhscolname;varcolname;valuecolname] ?[tblwide;enlist(~:;(^:;rhscolname));0b;(lhscolnames,varcolname,valuecolname)!lhscolnames,enlist[enlist rhscolname],rhscolname]};
q)raze wide2long[`k1`k2;;`index;`val] each (cols tblwide) except `k1`k2
k1 k2 index val
---------------
a t xx 1
a u xx 2
b t xx 3
b u xx 4
c t xx 5
c u xx 6
a t yy 11
a u yy 12
b t yy 13
b u yy 14
c t yy 15
c u yy 16
我认为您根本不需要
eval
。这样的方法应该适用于两种情况:
wide2long:{[lhscolnames;rhscolname;varcolname;valuecolname] ?[tblwide;enlist(~:;(^:;rhscolname));0b;(lhscolnames,varcolname,valuecolname)!lhscolnames,enlist[enlist rhscolname],rhscolname]};
q)raze wide2long[`k1`k2;;`index;`val] each (cols tblwide) except `k1`k2
k1 k2 index val
---------------
a t xx 1
a u xx 2
b t xx 3
b u xx 4
c t xx 5
c u xx 6
a t yy 11
a u yy 12
b t yy 13
b u yy 14
c t yy 15
c u yy 16
非常感谢Terry,“这很有效”。我可以请你对这篇文章发表评论吗!lhscolnames,enlist[enlist rhscolname],rhscolname我对此有点迷茫(我不知道如何在这个上下文中调查这3个术语的类型和值)。我的理解是,我们需要一本将键映射到列表的词典。然后lhscolnames包含列的名称,而rhscolname包含列的值,然后enlist enlist我根本不懂。。。(我使用parse和trial-and-error构建了这个东西的一半)您正在试图找到它的函数形式(特别是字典):
d:last parse“选择k1,k2,index:`xx,val:xx from tblwide where not null xx”
。生成键很简单:key[d]~lhscolnames、varcolname、valuecolname
。这些值比较复杂,因为对于索引列,您试图指定单词“xx”,而不是列“xx”。您可以通过登记“xx”来避免这种歧义。需要额外的登记来阻止kdb将两个符号列表追加到一个统一列表中。因此,value[d]~lhscolnames,enlist[enlist rhscolname],rhscolname
我想我明白了。谢谢你的解释。非常感谢特里,“它很有效”。我可以请你对这篇文章发表评论吗!lhscolnames,enlist[enlist rhscolname],rhscolname我对此有点迷茫(我不知道如何在这个上下文中调查这3个术语的类型和值)。我的理解是,我们需要一本将键映射到列表的词典。然后lhscolnames包含列的名称,而rhscolname包含列的值,然后enlist enlist我根本不懂。。。(我使用parse和trial-and-error构建了这个东西的一半)您正在试图找到它的函数形式(特别是字典):d:last parse“选择k1,k2,index:`xx,val:xx from tblwide where not null xx”
。生成键很简单:key[d]~lhscolnames、varcolname、valuecolname
。这些值比较复杂,因为对于索引列,您试图指定单词“xx”,而不是列“xx”。您可以通过登记“xx”来避免这种歧义。需要额外的登记来阻止kdb将两个符号列表追加到一个统一列表中。因此,value[d]~lhscolnames,enlist[enlist rhscolname],rhscolname
我想我明白了。谢谢你的解释。