apply dynamic projection to column

Say I’ve got the following dictionary of functions that I want to calculate on a table

q)t:(a:10?aabbcc;b:10?10;c:10?10f) q)d:avdvma!((avg;c);(dev;b);(mavg;;c))

av and dv are easy

q)![t;();{x!x}(),`a;-1_ d]

But I want to be able to apply the projection of `ma dynamically. I can get what I want by creating the projection in a query - something like

update ma:(first ma)[4]by a from update ma:mavg[;c]by a from t

but I’d like to do this in the functional form.

The projection of ma appears to pass a null as the first argument.

q)last parse"update ma:mavg[;c]by a from t"
ma| k){msum[x;0.0^y]%mcount[x;y]} :: `c

but when I attempt to use this in the functional form it doesn’t seem to work :

![t;();{x!x}(),a;enlist[ma]!enlist(mavg;::;`c)]

and duly gives me a 'type error on the null

Am I approaching this in the wrong way? Is there a better way?

You could project the mavg when you define the dictionary

 

q)d:avdvma!((avg;c);(dev;<wbr>b);(mavg[4];c))

q)

q)![t;();{x!x}(),`a;d]

a  b c        av       dv        ma

-----------------------------------------

aa 4 3.927524 5.708317 2.357023  3.927524

bb 6 5.170911 4.841748 2.061553  5.170911

cc 6 5.159796 3.685535 0.8164966 5.159796

bb 1 4.066642 4.841748 2.061553  4.618777

cc 8 1.780839 3.685535 0.8164966 3.470318

bb 5 3.017723 4.841748 2.061553  4.085092

aa 4 7.85033  5.708317 2.357023  5.888927

aa 9 5.347096 5.708317 2.357023  5.708317

bb 2 7.111716 4.841748 2.061553  4.841748

cc 7 4.11597  3.685535 0.8164966 3.685535

 

 

Or to make it even more dynamic, make d a function which returns a dictionary

 

q)d:{avdvma!((avg;c);(dev;b);(mavg[x];c))}

q)

q)![t;();{x!x}(),`a;d 4]

a  b c        av       dv        ma

-----------------------------------------

aa 4 3.927524 5.708317 2.357023  3.927524

bb 6 5.170911 4.841748 2.061553  5.170911

cc 6 5.159796 3.685535 0.8164966 5.159796

bb 1 4.066642 4.841748 2.061553  4.618777

cc 8 1.780839 3.685535 0.8164966 3.470318

bb 5 3.017723 4.841748 2.061553  4.085092

aa 4 7.85033  5.708317 2.357023  5.888927

aa 9 5.347096 5.708317 2.357023  5.708317

bb 2 7.111716 4.841748 2.061553  4.841748

cc 7 4.11597  3.685535 0.8164966 3.685535

 

 

Terry

How are you benefiting from deferring filling in this parameter?

Here’s another approach:

The template version ties the c column as an argument:

update ma:mavg[;c]by a from t

cc 6 4.046546 k){msum[x;0.0^y]%mcount[x;y]}[;4.046546 6.42737 9.030751 7.7502…

If I take out the :: and leave it empty, the c column is not tied in:

![t;();{x!x}(),a;enlist[ma]!enlist(mavg;;`c)]

cc 6 4.046546 enlist[k){msum[x;0.0^y]%mcount[x;y]};;`c]

Removing the second parameter altogether does tie the values, but in the wrong place:

![t;();{x!x}(),a;enlist[ma]!enlist(mavg;`c)]

cc 6 4.046546 k){msum[x;0.0^y]%mcount[x;y]}[4.046546 6.42737 9.030751 7.750292]

It appears that the empty parameter stops Q from tieing parameters in.

A workaround is to use a lambda:

![t;();{x!x}(),a;enlist[ma]!enlist({mavg[;x]};`c)]

cc 6 4.046546 k){msum[x;0.0^y]%mcount[x;y]}[;4.046546 6.42737 9.030751 7.7502