如何在 q 中将 table 从宽转向长
how to pivot table wide to long in 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)
顺序不重要真的我可以稍后重新排序...
我完全接受其他 simpler/faster 解决方案,但仍然很乐意了解如何使用 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
我正在尝试编写一个函数来将我的表格从宽格式转换为长格式。 所以我在这条线上有一些东西:
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)
顺序不重要真的我可以稍后重新排序...
我完全接受其他 simpler/faster 解决方案,但仍然很乐意了解如何使用 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