Wrong type error when creating a table with symbols with spaces in kdb/q - kdb

I am trying to create a table of symbols in kdb, where the values of the table have spaces within. I have got
tab:([colOne:`$"value 1"`$"value 2"]colTwo:`$"value 3"`$"value 4")
currently, but this just returns
ERROR: `type (wrong type)
i have followed http://www.kdbfaq.com/kdb-faq/tag/sym-with-a-space

Should be:
tab:([colOne:`$("value 1";"value 2")]colTwo:`$("value 3";"value 4"))
Remember that evaluation in q is left-to-right:
colTwo:`$"value 3"`$"value 4"
`$"value 4" will be evaluated to symbol
Then it will try to apply this symbol to what's on the left:
"value 3" `$"value 4"
which will give you 'type

you are right about sym with a space part but while creating a table columns take lists as inputs.
tab:([colOne:`a`b]colTwo:`c`d)
would be ok as `a`b is a list but when using syms with spaces you need to enclose them in () to make a list.
below will also work though sergey's answer is a better way of doing it.
tab:([colOne:(`$"value 1";`$"value 2")]colTwo:(`$"value 3";`$"value 4"))

Related

kdb: differences between value and eval

From KX: https://code.kx.com/q/ref/value/ says, when x is a list, value[x] will be result of evaluating list as a parse tree.
Q1. In code below, I understand (A) is a parse tree, given below definition. However, why does (B) also work? Is ("+";3;4) a valid parse tree?
q)value(+;3;4) / A
7
q)value("+";3;4) / B
7
q)eval(+;3;4) / C
7
q)eval("+";3;4) / D
'length
[0] eval("+";3;4)
Any other parse tree takes a form of a list, of which the first item
is a function and the remaining items are its arguments. Any of these
items can be parse trees. https://code.kx.com/q/basics/parsetrees/
Q2. In below code, value failed to return the result of what I think is a valid parse tree, but eval works fine, recursively evaluating the tree. Does this mean the topmost description is wrong?
q)value(+;3;(+;4;5))
'type
[0] value(+;3;(+;4;5))
^
q)eval(+;3;(+;4;5))
12
Q3. In general then, how do we choose whether to use value or eval?
put simply the difference between eval and value is that eval is specifically designed to evaluate parse trees, whereas value works on parse trees among other operations it does. For example value can be used to see the non-keyed values of dictionaries, or value strings, such as:
q)value"3+4"
7
Putting this string instead into the eval, we simply get the string back:
q)eval"3+4"
"3+4"
1 Following this, the first part of your question isn't too bad to answer. The format ("+";3;4) is not technically the parsed form of 3+4, we can see this through:
q)parse"3+4"
+
3
4
The good thing about value in this case is that it is valuing the string "+" into a the operator + and then valuing executing the parse tree. eval cannot understand the string "+" as this it outside the scope of the function. Which is why A, B and C work but not D.
2 In part two, your parse tree is indeed correct and once again we can see this with the parse function:
q)parse"3+(4+5)"
+
3
(+;4;5)
eval can always be used if your parse tree represents a valid statement to get the result you want. value will not work on all parse tree's only "simple" ones. So the nested list statement you have here cannot be evaluated by value.
3 In general eval is probably the best function of choice for evaluating your parse trees if you know them to be the correct parse tree format, as it can properly evaluate your statements, even if they are nested.

LIKE expression is not returning expected results. Issue or lack of understanding? (Probably the latter)

Using LIKE '%[0-9]%' to find "yellow 2 x 4 plate".
This is a simplified example that isn't working as I believe it should.
Table (command) with single column (commandtext, varchar).
Single entry in commandtext: yellow 2 x 4 plate.
SELECT
*
FROM command
WHERE commandtext LIKE '%[0-9]%'
Results = Empty set.
I expect that all this should be looking for is a digit between 0-9 surrounded by anythings else.
I am CLEARLY not getting something here...
As you have found out, you can use SQL standard SIMILAR TO:
... WHERE col SIMILAR TO '%[[:digit:]]%'
You could also use POSIX regular expressions:
... WHERE col ~ '[[:digit:]]'

Adding/Removing from String kdb

I was doing some work to do with kdb and have been tinkering with strings and variables. I was just wondering if its possible to remove part of a string and add something to do the end of it.
s1:"Hello" s2:" World"
I have a joint string "Hello World" which I created using
s3:s1,s2
I was trying to remove the Hello and add something after the World in the joint string.
s3[1*til 6] = Hello
This allows me to select the Hello part of the string if this helps
you could use drop (_) to get rid of the "Hello" and join (,) to add on what you want. Something like
q)6_s3,"star Hiphop"
"Worldstar Hiphop"
If you didn't want to count the letters in the first word you could use vector from scalar (vs) to get a list of enlisted words and index into it, then join onto that:
q)(" " vs s3)[1],"star Hiphop"
"Worldstar Hiphop"
Hope this helps.
Strings are character lists, so the drop function _ will still work on them. For example 1_"Hello" will return ello.
So if you want to remove "Hello" from your string s3 you would use
q)5_s3
"World"
Adding something onto the end of this then requires the join operator ,, for example
q)s:"HelloWorld"
q)s1:"Mr. "
q)s2:5_s
q)s3:"wide"
q)s1,s2,s3
"Mr. Worldwide"
You could use the ssr function (string search replace).
q)s3:"HelloWorld"
q)ssr[s3;"Hello";""], " of War"
"World of War"

I am a beginner in Q. Got multiple questions related to Q

When I type l: 1 2, I get back list of 1,2. But when I type
string: a b, why I get back `assign?
What does ` sign does in Q? What is its significance?
When I type string: a b, why do I get back `assign?
The "assign" error means an "attempt to redefine a reserved word". See Runtime Errors. For the list of reserved words, see Reserved Words.
What does ` sign do in Q?
A back tick ` followed by a series of characters represents a symbol. For more details, see Symbols.
Note that q distinguishes between the back tick, ` and the single quote, '. When prints an error, it uses a single quote. For other uses, see Case.

converting 1x1 matrix to a variable

I read the data from the csv which contains two columns id which text/string and the cancer which is 1/0. please see the code be
M = readtable('data.csv');
I try to access the very first value using
row= M(n,1); //It's from the ID column which is text
But it comes in the form of a 1x1matrix, and I am unable to put it in a single variable.
for example I want after the above line works row should contain a string in it like. row = 'patientID'. Now is there anyway to convert it into a single value?
Use row = M{n,1}. Note the curly braces.
The curly braces say "get the contents of the table", as opposed to the circular brackets you had been using which say "get me a portion of the table, as a table".