Adding Columns in kdb based on other columns value - kdb

I have a column like this in dataframe named test:
Name Client
A P
B Q
C R
D S
E T
I need to to create a new column clienttype in the same dataframe with condition that, if Client = P or Q clienttype = first. If client type = R or S clienttype = second and so on. Can anyone tell how to do this in kdb? Thanks

Could this be solved with a dictionary?
q)update ClientType:(`P`Q`R`S!`first`first`second`second)Client from tab
Name Client ClientType
----------------------
A P first
B Q first
C R second
D S second
E T
Extension to this: You can also use vector conditionals ?[;;] for these types of problems. Unfortunately in this case in would result in many nested vector conditionals:
update Clienttype:?[Client in`P`Q;`first;?[Client in`R`S;`second;`third]]from tab
Name Client Clienttype
----------------------
A P first
B Q first
C R second
D S second
E T third
If you only had two possible options (e.g. first and second) this approach could prove useful.

You did not tell us the types of the columns in your table, but if all your entries are single letter, they are best represented by q char type:
q)show t:([]Name:"ABCDE";Client:"PQRST")
Name Client
-----------
A P
B Q
C R
D S
E T
Now, the Clienttype is best stored as a number which can be computed as
q)update Clienttype:1+(("i"$Client)-"i"$"P")div 2 from t
Name Client Clienttype
----------------------
A P 1
B Q 1
C R 2
D S 2
E T 3
or if you must use symbols,
q)types:`first`second`third`fourth
q)update Clienttype:types(("i"$Client)-"i"$"P")div 2 from t
Name Client Clienttype
----------------------
A P first
B Q first
C R second
D S second
E T third

Related

How does chisel connect to such a port?

I am learning the design of Boomv3.
The A part has a write port. The format is
val write_ports = Flipped(Vec(10, Valid(new RegisterFileWritePort(maxPregSz, registerWidth))))
B has a write port. The format is
val write_ports = Vec(5, Valid(new RegisterFileWritePort(maxPregSz, 4)))
C has a write port. The format is
val write_ports = Vec(5, Valid(new RegisterFileWritePort(maxPregSz, 4)))
I want to connect B and C to A.
When i use
A.write_ports <> B.write_ports
A.write_ports <> C.write_ports
, here will be a failed #: Left and Right are different length Vecs error.
But my original intention is that the length of A is 10. The length of B and C are both 5. This makes them connect.
But what should I do?
With these two bulk connexions, Chisel can't find where to assign B and C 5-sized Vec to B 10-sized Vec.
You should concatenate B and C vec and write one bulk connexion :
A.write_ports <> B.write_ports ++ C.write_ports
I tested it with scatie here.

Accessing external (DSPF) fields using arrays in RPGLE free

In the old RPG III and the non-free RPGLE/RPG IV you could "rename" fields you get from either a record of a PF/LF or a record from a DSPF.
This lead to possibilities like grouping several lines of input (additional order text) into a array. So I didn't have to MOVEL or EVAL ottxt1 to the external described field x1txt1, ottxt2 to x1txt2 and so on.
I'd only had to rename the LF record and the DSPF record fields to the array-fields, read the record and shift them from the one array to the other and display my DSPF record
H DECEDIT('0,') DATEDIT(*DMY.) dftactgrp(*no)
Fsls001 cf e workstn
Fordtxtl0 if e k disk
D ot s 20a dim(6)
D x1 s 20a dim(6)
Iordtxtr
I ottxt1 ot(1)
I ottxt2 ot(2)
I ottxt3 ot(3)
I ottxt4 ot(4)
I ottxt5 ot(5)
I ottxt6 ot(6)
Isls00101
I x1txt1 x1(1)
I x1txt2 x1(2)
I x1txt3 x1(3)
I x1txt4 x1(4)
I x1txt5 x1(5)
I x1txt6 x1(6)
C k$or00 klist
C kfld otonbr
C kfld otopos
C eval otonbr = 2
C eval otopos = 2
C k$or00 chain ordtxtr
C if %found(ordtxtl0)
C eval x1 = ot
C endif
C
C exfmt sls00101
C
C move *on *inlr
But is this also possible in *FREE RPGLE? And if so, how?
You can define data structures containing the fields from the files, and overlay them with an array.
Replace your I specs and array definitions with these data structures. You don't have to specify anything besides the field names for the fields from the externally-described file.
dcl-ds otDs;
ottxt1;
ottxt2;
ottxt3;
ottxt4;
ottxt5;
ottxt6;
ot like(ottxt1) dim(6) pos(1);
end-ds;
dcl-ds x1Ds;
x1txt1;
x1txt2;
x1txt3;
x1txt4;
x1txt5;
x1txt6;
x1 like(x1txt1) dim(6) pos(1);
end-ds;

apply multiple vector to function

I have a simple function which returns a table:
F[("A";"B");(1,-1)]
I would like to apply this function passing vectors as inputs:
a:((`A;`B);(`B;`C);(`C;`D))
b:((1;-1);(1;-1);(1;-1))
I have tried:
F each a,b
F each a cross b
but this doesn't work or combines the vectors rather than keeping the 2 components separate. In addition when I do get it to work how do I row bind the resulting list of tables? I am coming from a python background.
You need to use ' each-both :
q)F:{ ([] enlist x; enlist y)} /if F is simply creating a table
q)F[("A";"B");(1,-1)]
x y
---------
"AB" 1 -1
q)a:((`A;`B);(`B;`C);(`C;`D))
q)b:((1;-1);(1;-1);(1;-1))
q)F'[a;b] /each-both
+`x`y!(,`A`B;,1 -1)
+`x`y!(,`B`C;,1 -1)
+`x`y!(,`C`D;,1 -1)
raze will format it to a table (i think row binding means appending the tables together)
q)raze F'[a;b]
x y
--------
A B 1 -1
B C 1 -1
C D 1 -1

kdb apply function in select by row

I have a table
t: flip `S`V ! ((`$"|A|B|"; `$"|B|C|D|"; `$"|B|"); 1 2 3)
and some dicts
t1: 4 10 15 20 ! 1 2 3 5;
t2: 4 10 15 20 ! 0.5 2 4 5;
Now I need to add a column with values on the the substrings in S and the function below (which is a bit pseudocode because I am stuck here).
f:{[s;v];
if[`A in "|" vs string s; t:t1;];
else if[`B in "|" vs string s; t:t2;];
k: asc key t;
:t k k binr v;
}
problems are that s and v are passed in as full column vectors when I do something like
update l:f[S,V] from t;
How can I make this an operation that works by row?
How can I make this a vectorized function?
Thanks
You will want to use the each-both adverb to apply a function over two columns by row.
In your case:
update l:f'[S;V] from t;
To help with your pseudocode function, you might want to use $, the if-else operator, e.g.
f:{[s;v]
t:$["A"in ls:"|"vs string s;t1;"B"in ls;t2;()!()];
k:asc key t;
:t k k binr v;
};
You've not mentioned a final else clause in your pseudocode but $ expects one hence the empty dictionary at the end.
Also note that in your table the columns S and V have been cast to a symbol. vs expects a string to split so I've had to use the stringoperation - this could be removed if you are able to redefine your original table.
Hope this helps!

Calculator doesn't execute the operations

I am trying to build a calculator in abap. The requirements are:
Reads
two numbers (ex. 56.3 and 78.2)
a character from the following list: q, w, e, r, t
Displays the result of the operation specified by the character
Addition for character q
Subtraction for character w
Multiplication for character e
Division for character r
Exponent for character t
I have created a table with the operations that I am using in the calculator.
The problem is when I execute the program it only prints my last option (else) "the operation is not possible".
Here's the code I wrote:
REPORT Z_CALCULATOR_V2.
TABLES: ZOPERATII.
DATA result type p decimals 2.
DATA Q type c.
DATA W like Q.
DATA E like Q.
DATA R like Q.
DATA T like Q.
PARAMETERS Nr_1 type p decimals 2 OBLIGATORY.
PARAMETERS Nr_2 like Nr_1 OBLIGATORY.
PARAMETERS Operatie LIKE zoperatii-operatie OBLIGATORY.
if Operatie = Q.
result = Nr_1 + Nr_2.
elseif Operatie = W.
result = Nr_1 - Nr_2.
elseif Operatie = E.
elseif Operatie = R.
result = Nr_1 / Nr_2.
elseif Operatie = T.
result = Nr_1 ** Nr_2.
else.
WRITE 'The operation is not possible'.
endif.
write result.
if you change the data declarations to:
DATA Q type c value 'Q'.
DATA W type c value 'W'.
DATA E type c value 'E'.
DATA R type c value 'R'.
DATA T type c value 'T'.
the code should run as you expect. That said, you should read up on the documentation as suggested in the comments.