KDB+/Q - over (/) 2 lists of values - functional-programming

How to use "over" on 2 lists of inputs, each time picking 1 element from the 2 lists?
E.g., there is:
(+/)[1;2 3] = +[+[1;2];3] = 6
How to do something like:
f:{x+y+z};
(f/)[1;2 3;22 33] = f[f[1;2;22];3;33] = 61
Thank you.

This should work exactly as you described, which is the fold behaviour of over /. When using it with 3 arguments the function cycles through lists of y and z applying them to the output of the previous expression. Considering the numbers you have provided:
x:1
y:2 3
z:22 33
The wiki page describes this as:
f[f[… f[f[x;y0;z0];y1;z1]; … yn-1;zn-1];yn;zn]
Which is pseudocode looks something like:
res = x + y[0] + z[0] // pass this value forward
= res + y[1] + z[1]

"over" takes two arguments each time, so three arguments is not an option: http://code.kx.com/q/ref/control/#over
To achieve what you have mentioned, the function as well as the input have to be twisted:
f:{x+y[0]+y[1]}
(f/)1,flip(2 3;22 33)

Related

Plotting like Excel

I had a vector like this :
x= c(0.542949849, 0.242292905, 0.163459552, 0.069668097, 0.042969073, 0.035829825)
and I want to plot (x[i], x[i+1]). Using Excel I got this :
How can I get this graphic in R ? I tried this :
for(i in 1:5){
plot(x[i], x[i+1])
par(new = TRUE)
}
but it doesn't give the excepted result
Here are two solutions.
The first uses base R only.
x <- c(0.542949849, 0.242292905, 0.163459552, 0.069668097, 0.042969073, 0.035829825)
plot(range(x), range(x), type = "n")
for(i in seq_along(x)[-length(x)]){
points(x[i], x[i+1])
}
The second uses package tsDyn.
tsDyn::autopairs(x, type = "points")
Try this:
plot(embed(rev(x), 2))
or
plot(embed(x, 2)[, 2:1])
You can get what you want but you have to add a few intermediate steps.
You need to put in a qualifier to force the array to be numeric. This is the equivalent of forcing the array to be an array of float values. Otherwise all you get is integer values in your array.
You need to redefine the sub-components of x to 2 new vectors. Vector 'a' has an index of elements from 1 to 5 of the x array. It appears on the x-axis. Vector 'b' has an index of elements from 2 to 6 of the x array. It appears on the y-axis. The first elements in vectors a and b index position 1 are equivalent to x[i],x[i+1] where i is 1.
You need to bind the 2 vectors together and then plot the result.
x <- as.numeric(c(0.542949849, 0.242292905, 0.163459552, 0.069668097, 0.042969073, 0.035829825))
a <- x[1:5]
b <- x[2:6]
c <- cbind(a,b)
plot(c)
and the result graph is as follows

R:Run randomly any of four lines /commands

I have 4 differents lines/commands (the addition is just an example)
one<- (1+1)
two<- (2+2)
three<-(3+3)
four<-(4+4)
I need to run randomly any of this four command lines (one, two, three or four), I am no focus in the addition result.
I did try with:
list=c("one", "two", "three", "four")
number <- sample(list, 1)
number
but lamentably didnt run the line/command.
I expect that the sampling can run on the console any of these 4 commands.
Thanks in advance
Seems like maybe the problem is that you aren't constructing the list correctly? Does this do what you expect?
one <- (1+1)
two <- (2+2)
three <- (3+3)
four <- (4+4)
myList <- list(one, two, three, four)
number <- sample(myList, 1)[[1]]
Because (1 + 1) evaluated to 2 and that 2 is assigned to one, it is impossible to retrieve (1 + 1) through one (if you define it the way you did). If you want to capture 1 + 1, etc, you can do the following:
one = quote(1 + 1)
two = quote(2 + 2)
three = quote(3 + 3)
ls = list(one, two, three)
x = sample(ls, 1)[[1]]
x # expression like 1 + 1
eval(x) # evaluated sum

Multiply unique pairs of values in a vector and sum the result

I want to multiply and then sum the unique pairs of a vector, excluding pairs made of the same element, such that for c(1:4):
(1*2) + (1*3) + (1*4) + (2*3) + (2*4) + (3*4) == 35
The following code works for the example above:
x <- c(1:4)
bar <- NULL
for( i in 1:length(x)) { bar <- c( bar, i * c((i+1) : length(x)))}
sum(bar[ 1 : (length(bar) - 2)])
However, my actual data is a vector of rational numbers, not integers, so the (i+1) portion of the loop will not work. Is there a way to look at the next element of the set after i, e.g. j, so that I could write i * c((j : length(x))?
I understand that for loops are usually not the most efficient approach, but I could not think of how to accomplish this via apply etc. Examples of that would be welcome, too. Thanks for your help.
An alternative to a loop would be to use combn and multiply the combinations using the FUN argument. Then sum the result:
sum(combn(x = 1:4, m = 2, FUN = function(x) x[1] * x[2]))
# [1] 35
Even better to use prod in FUN, as suggested by #bgoldst:
sum(combn(x = 1:4, m = 2, FUN = prod))

Check the differences in a vector and select the ones that provide positive output

I need to check the differences (p_k - (p_k-1)) and select the ones that provide positive result, e.g.
7-5 = 2 (positive)
8-7 = 1 (positive)
6-8 = -2 (negative: cut it off)
etc.
I use the following data:
p <- c(5,7,8,6,5,7,12)
This is what I tried, but it provides logical true/false outputs (not numeric):
result <- diff(p)>0
if your looking for the values {k} such that (p_k > p_(k-1), then you want
result = which(diff(p)>0) + 1
(The + 1 is because in your notation k is the larger of the pair [k, k -1])

R: sequentially applying an arbitrarty list of functions with arguments to a matrix

I have a list of filtering functions f1,f2,f3,f4,.... which take a matrix m and a number of options as input and return a subset of the rows of matrix as output. Now I would like to be able to define in an orderly way some meta-filtering function settings metaf1, metaf2, metaf3,... which would specify the sequential application of a specified nr of filtering functions, e.g. first f2 and then f3, using given options for each. I would like to store these filtering settings in a list of say class "metafiltering", and then have another function apply the filtering steps specified in a given metafiltering object. My idea would be able to in this way allow filtering settings to be stored and applied in an orderly way. How would I achieve this in the most elegant way in R? Or is there perhaps other convenient methods to achieve something like this?
EDIT: to give an example, say I have matrix
m=replicate(10, rnorm(20))
and filtering functions (these are just examples, obviously mine are more complicated :-) )
f1=function(m,opt1,opt2) {
return(m[(m[,2]>opt1)&(m[,1]>opt2),])
}
f2=function(m,opt1) {
return(m[(m[,3]>opt1),])
}
And I have defined the following metafiltering settings of specific class which would specify two functions which would have to be applied sequentially to matrix m
metafilterfuncs=list(fun1=f1(opt1=0.1,opt2=0.2),fun2=f2(opt1=0.5))
class("metafilterfuncs")="metafiltering"
The question I have then is how I could apply the filtering steps of an arbitrary metafiltering function object to given matrix m using the specified functions and settings?
You can do something like this :
You define a sort of functions pieplines where you give a priority for each function.
pipelines <- c(f1=100,f2=300,f3=200)
I define 3 dummy functions here for test:
f1 <- function(m,a) m + a
f2 <- function(m,b) m + b
f3 <- function(m,c) m + c
For each function , you store the argument in another list :
args <- list(f1=c(a=1),f2=c(b=2),f3=c(c=3))
Then you apply your functions :
m <- matrix(1:2,ncol=2)
for (func in names(pipelines[order(pipelines)]))
{
m <- do.call(func,list(m,args[[func]]))
}
pryr has a function, compose, like what you need, but it doesn't quite cut it. The compose function requires the functions to be given one by one, not in a list, and it cannot take arguments. It's also oddly placed in that package. A similar function can be found in plyr, namely each. But this function does not apply functions sequentially, but individually and outputs a named vector (list?).
agstudy provided a solution above, but it suffers from a problem: it can only take scalar arguments because it gives the arguments in a named vector. The solution to this is to use a named list instead. So, here's an improved function to replace the one in pryr.
compose2 = function(x, funcs, args, msg_intermediate = F) {
if (length(funcs) != length(args)) stop("length of functions and arguments must match")
for (i in seq_along(funcs)) {
x = do.call(what = funcs[[i]], args = c(x, args[[i]]))
if ((i != length(funcs)) && msg_intermediate) message(x)
}
x
}
msg_intermediate is a nice debugging argument that messages the intermediate results, so one can easier understand what happens.
Test it:
adder = function(x, n) x + n
compose2(0,
funcs = list(adder, adder, adder),
args = list(list(n = 1), list(n = 2), list(n = 3)),
msg_intermediate = T
)
Outputs:
1
3
[1] 6
This is what you get when you take 0, then add 1 (=1), then add 2 (=3), then add 3 (=6).
The args argument for compose2 takes a list of lists, so that one can supply non-scalar function arguments. Here's an example:
add_div = function(x, n, d) (x + n) / d
compose2(0,
funcs = list(add_div, add_div, add_div),
args = list(list(n = 1, d = 1), list(n = 2, d = 2), list(n = 3, d = 3)),
msg_intermediate = T
)
Output:
1
1.5
[1] 1.5
Which is what you get when you take 0, add 1, divide by 1 (=1), then take 1, add 2 then divide by 2 (=1.5), then take 1.5, add 3 and then divide by 3 (=1.5).

Resources