首页 > 解决方案 > 如何在q中将表格从宽变为长

问题描述

我正在尝试编写一个函数来将我的表格从宽格式转换为长格式。所以我在这行有一些东西:

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.

标签: kdb

解决方案


我认为你根本不需要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 

推荐阅读