Manipulating expressions in R - r

I am looking for a way to create an expression that is the product of two given expressions. For example, suppose I have
e1 <- expression(a+b*x)
e2 <- expression(c+d*x)
Now I want to create programatically the expression (e1)*(e2):
expression((a+b*x)*(c+d*x))
Background
I am writing a model fitting function. The model has two pieces that are user-defined. I need to be able to "handle" them separately, and then create a combined expression and "handle" it as one model. "Handling" involves taking numeric derivatives, and the deriv function wants expressions as an input.

I don't deal with this too often but something like this seems to be working
e1 <- expression(a + b*x)
e2 <- expression(c + d*x)
substitute(expression(e1*e2), list(e1 = e1[[1]], e2 = e2[[1]]))
# expression((a + b * x) * (c + d * x))

Try this:
e1 <- quote(a+b*x) # or expression(*)[[1]]
e2 <- quote(c+d*x)
substitute(e1 * e2, list(e1=e1, e2=e2))

It's probably overkill in your case, but the Ryacas package can be nice for performing more complicated symbolic manipulations of this sort:
library(Ryacas)
yacas(expression(e1*e2))$text
# expression((a + b * x) * (c + d * x))
Also, instead of using substitute(), you can construct the same expression in base R like this:
as.expression(as.call(list(as.symbol("*"), e1[[1]], e2[[1]])))
# expression((a + b * x) * (c + d * x))
Explanatory note: One initially confusing aspect of dealing with expression objects is that they are really lists of language objects -- even when (as is often the case) those lists contain just one object. For example, in your question, both e1 and e2 are length 1 lists containing a single call object each.
Working from the inside out, the code above:
Extracts the two call objects using [[1]]
Uses as.call() to constructs a new call that is the product of the two call objects.
Finally, wraps the resultant call back up as the expression object that you want.

Related

Julia - Understanding LinearMaps example

I am trying to wrap my head around the LinearMaps.jl package. In their documentation they have only two examples and I am stuck at the first one.
# Define a linear map from a matrix and one from a function (?)
A = LinearMap(rand(10, 10))
B = LinearMap(cumsum, reverse∘cumsum∘reverse, 10)
# Possible operations
3.0A + 2B
A + I
A*B'
[A B; B A]
kron(A, B)
How does LinearMap() work when its argument(s) are functions? For instance the cumsum() function doesn't work on its own as it requires the dims argument, so I am completely puzzled as to what this is doing.

How to use Deriv with a matrix structure in r

I am computing a partial derivative using Deriv for the function below but I keep getting errors probably because Deriv can not understand the symbols I am using within my defined function.
m1 and m2 have 3 elements each or you would think of it as a matrix of 3 columns and 2 rows where each row represents each m_i
I have defined the function f in r as:
f <- function(m,q){
structure(vapply(seq(3), function(j)
12 * log(sum(vapply(seq(2), function(i) exp(m[i,j]) * q[i], double(1))) + q[3]),
double(1)), dim=c(1,3))
}
The i's and j's are only useful because I am planning to broaden the function. Could there be a way I would define this function so that I am able to compute the f1 as defined above?
f1 = Deriv(f, "m[i, ]")
Or could there be any other package that could handle such a problem?

How to split a "formula" in R

I'm trying to make a small R package with my limited knowledge in R programming. I am trying to use the following argument:
formula=~a+b*X
where X is vector, 'a' and 'b' are constants in a function call.
What I'm wondering is once I input the formula, I want to extract (a,b) and X separately and use them for other data manipulations inside the function call. Is there a way to do it in R?
I would really appreciate any guidance.
Note: Edited my question for clarity
I'm looking for something similar to model.matrix() output. The above mentioned formula can be more generalized to accommodate 'n' number of variables, say,
~2+3*X +4*Y+...+2*Z
In the output, I need the coefficients (2 3 4 ...2) as a vector and [1 X Y ... Z] as a covariate matrix.
The question is not completely clear so we will assume that the question is, given a formula using standard formula syntax, how do we parse out the variables names (or in the second answer the variable names and constants) giving as output a character vector containing them.
1) all.vars Try this:
fo <- a + b * X # input
all.vars(fo)
giving:
[1] "a" "b" "X"
2) strapplyc Also we could do it with string manipulation. In this case it also parses out the constants.
library(gsubfn)
fo <- ~ 25 + 35 * X # input
strapplyc(gsub(" ", "", format(fo)), "-?[0-9.]+|[a-zA-Z0-9._]+", simplify = unlist)
giving:
[1] "25" "35" "X"
Note: If all you are trying to do is to evaluate the RHS of the formula as an R expression then it is just:
X <- 1:3
fo <- ~ 1 + 2 * X
eval(fo[[2]])
giving:
[1] 3 5 7
Update: Fixed and added second solution and Note.
A call is a list of symbols and/or other calls and its elements can be accessed through normal indexing operations, e.g.
f <- ~a+bX
f[[1]]
#`~`
f[[2]]
#a + bX
f[[2]][[1]]
#`+`
f[[2]][[2]]
#a
However notice that in your formula bX is one symbol, you probably meant b * X instead.
f <- ~a + b * X
Then a and b typically would be stored in an unevaluated list.
vars <- call('list', f[[2]][[2]], f[[2]][[3]][[2]])
vars
#list(a, b)
and vars would be passed to eval at some point.

How to override binary operator for integer or numeric type?

I'm trying to override the binary operators like + or - that receive two integers or two numeric without setting class attribute.
First, I tried setMethod. But It doesn't re-define sealed operator
Second, I tried to write Ops.{class} like this link
But it didn't work without setting class to S3 objects.
So, I want to know how to override + and - methods that takes integers or numerics without a class attributes.
If you just want to override + and - for numerics you can do that. Here's an example:
`+` <- function(x,y) x * y
2 + 3
[1] 6
Of course, after you've done this, you can't use + in the normal way anymore (but for reasons beyond me it seems that's what you want).
If you need some special arithmetics for numerics,it is easier to define infix operators with the %<operator>% notation. Here's an example defining the operations from max-plus algebra
`%+%` <- function(x,y) pmax(x,y) #(use pmax for vectorization)
`%*%` <- function(x,y) x + y
2 %+% 3
[1] 3
2 %*% 3
[1] 5
Another option is to define a special number class. (I'll call it tropical in the following example since max-plus algebra is a variant of tropical algebra)
setClass("tropical",slots = c(x="numeric"))
# a show method always comes in handy
setMethod("show","tropical",function(object){
cat("tropical vector\n")
print(object#x)
})
# its also nice to have an extractor
setMethod("[","tropical",function(x,i,j,...,drop) new("tropical",x=x#x[i]) )
setMethod("+",c("tropical","tropical")
, function(e1,e2) new("tropical", x=pmax(e1#x,e2#x))
setMethod("*",c("tropical","tropical")
, function(e1,e2) new("tropical", x= e1#x + e2#x))
# try it out
tr1 <- new("tropical",x=c(1,2,3))
tr2 <- new("tropical",x=c(3,2,1))
tr1 + tr2
tr1 * tr2
# this gives a warning about recycling
tr1[1:2] + tr2

parameter passing mechanism in R

The following function is used to multiply a sequence 1:x by y
f1<-function(x,y){return (lapply(1:x, function(a,b) b*a, b=y))}
Looks like a is used to represent the element in the sequence 1:x, but I do not know how to understand this parameter passing mechanism. In other OO languages, like Java or C++, there have call by reference or call by value.
Short answer: R is call by value. Long answer: it can do both.
Call By Value, Lazy Evaluation, and Scoping
You'll want to read through: the R language definition for more details.
R mostly uses call by value but this is complicated by its lazy evaluation:
So you can have a function:
f <- function(x, y) {
x * 3
}
If you pass in two big matrixes to x and y, only x will be copied into the callee environment of f, because y is never used.
But you can also access variables in parent environments of f:
y <- 5
f <- function(x) {
x * y
}
f(3) # 15
Or even:
y <- 5
f <- function() {
x <- 3
g <- function() {
x * y
}
}
f() # returns function g()
f()() # returns 15
Call By Reference
There are two ways for doing call by reference in R that I know of.
One is by using Reference Classes, one of the three object oriented paradigms of R (see also: Advanced R programming: Object Oriented Field Guide)
The other is to use the bigmemory and bigmatrix packages (see The bigmemory project). This allows you to create matrices in memory (underlying data is stored in C), returning a pointer to the R session. This allows you to do fun things like accessing the same matrix from multiple R sessions.
To multiply a vector x by a constant y just do
x * y
The (some prefix)apply functions works very similar to each other, you want to map a function to every element of your vector, list, matrix and so on:
x = 1:10
x.squared = sapply(x, function(elem)elem * elem)
print(x.squared)
[1] 1 4 9 16 25 36 49 64 81 100
It gets better with matrices and data frames because you can now apply a function over all rows or columns, and collect the output. Like this:
m = matrix(1:9, ncol = 3)
# The 1 below means apply over rows, 2 would mean apply over cols
row.sums = apply(m, 1, function(some.row) sum(some.row))
print(row.sums)
[1] 12 15 18
If you're looking for a simple way to multiply a sequence by a constant, definitely use #Fernando's answer or something similar. I'm assuming you're just trying to determine how parameters are being passed in this code.
lapply calls its second argument (in your case function(a, b) b*a) with each of the values of its first argument 1, 2, ..., x. Those values will be passed as the first parameter to the second argument (so, in your case, they will be argument a).
Any additional parameters to lapply after the first two, in your case b=y, are passed to the function by name. So if you called your inner function fxn, then your invocation of lapply is making calls like fxn(1, b=4), fxn(2, b=4), .... The parameters are passed by value.
You should read the help of lapply to understand how it works. Read this excellent answer to get and a good explanation of different xxpply family functions.
From the help of laapply:
lapply(X, FUN, ...)
Here FUN is applied to each elementof X and ... refer to:
... optional arguments to FUN.
Since FUN has an optional argument b, We replace the ... by , b=y.
You can see it as a syntax sugar and to emphasize the fact that argument b is optional comparing to argument a. If the 2 arguments are symmetric maybe it is better to use mapply.

Resources