I have an expression stored in a variable
a <- expression(10 + x + y)
I want to use substitute to fill the expression with x = 2
substitute(a, list(x=2))
But this returns a and a evaluates to expression(10 + x + y)
Ideally a would evaluate to expression(12 + y) (or (10 + 2 + y))
Is there any way to implement this behavior while using an expression stored in the variable a (mandated by other parts of my project)?
Use do.call. substitute won't descend into some objects but if you use a[[1]] here then it will work.
a <- expression(10 + x + y)
do.call("substitute", list(a[[1]], list(x = 2)))
## 10 + 2 + y
You could do that with pryr if you can use an alternative (i.e. quote instead of expression):
a <- quote(10 + x + y)
library(pryr)
substitute_q(a, list(x=2))
#10 + 2 + y
Maybe this one snippet can be useful
x <- 1; y <- 2
a <- expression(10 + x + y)
eval(a)
Related
With Ryacas, one has:
> yac_str("Simplify(2*x^2*4 + x^2*5)")
[1] "13*x^2"
Now, instead of 4 and 5, I would like to give two letters treated as constants. That is, Ryacas does:
> yac_str("Simplify(2*x^2*a + x^2*b)")
[1] "2*x^2*a+x^2*b"
but I would like that it treats x as an unknown variable and a and b as constants, i.e. I would like to get the result:
(2*a+b)*x^2
I spent one hour to try with no luck. Is it possible? Otherwise, with another package?
This seems to be just how yacas wants to simplify that expression. SymPy does it the way you want though, and it has an R wrapper called caracas
library(caracas)
a <- as_sym("a")
b <- as_sym("b")
x <- as_sym("x")
caracas::simplify(2*x^2*a+x^2*b)
#> [caracas]: 2
#> x *(2*a + b)
I don't like the way it prints x^2, but you can't have everything.
I found the way with caracas.
library(caracas)
def_sym(x, y, z, a, b)
as.character(sympy_func(x^2 + a*x^2 + 2*y + b*y + x*z + a*x*z, "Poly", domain = "RR[a,b]"))
# "Poly((1.0*a + 1.0)*x^2 + (1.0*a + 1.0)*x*z + (1.0*b + 2.0)*y, x, y, z, domain='RR[a,b]')"
You can also work with rational numbers:
poly <-
sympy_func(x^2 + a*x^2 + 2/3*y + b*y + x*z + a*x*z, "Poly", domain = "QQ[a,b]")
as.character(poly)
# "Poly((a + 1)*x^2 + (a + 1)*x*z + (b + 2/3)*y, x, y, z, domain='QQ[a,b]')"
To get the coefficient of a term, e.g. xz (i.e. x^1y^0z^1):
sympy <- get_sympy()
sympy$Poly$nth(poly$pyobj, 1, 0, 1)
# a + 1
Is it possible in R to write a function f(x) like
f(x) = a_0 + a_1*sin(x) + ... + a_n*sin(n*x)
for some n, or any other f_i(x) in place of sin(i*x) just varying on i? I tried a recursion like
f <- function(x) a_0
for(n in 1:N)
f <- function(x) f(x) + a_n*x^n
It seemed to work but when I used f(x) to make some computations R said there was too much nesting. I eventually wrote by hand a_0 + a_1*x + ... etc.
Is there a proper way to do it in a compact way without using recursion?
If you have the following values of a and x
a <- 1:5
x <- 3
a[1] + a[2]*sin(x*1) + a[3]*sin(x*2) + a[4]*sin(x*3) + a[5]*sin(x*4)
# [1] -0.5903971
Then you can get the same value using
f <- function(x) {
a[1] + sum( a[-1] * sin((x * seq.int(length(a)-1) )))
}
f(x)
#[1] -0.5903971
Note that arrays in R use 1-based indexing
I am using R and trying to make an function by giving 2 parameters which are function and x, try to look for the answer of the function. But I kept getting error. I do not want to use any packages just solely R base.
Heres the Code so far.
test2 <- function(x) {
func <- expression(x)
der<- D(eval(func), 'x')
return(der(x))
}
test2(function(x) return(x^2))
I kept getting this error: "expression must not be type 'closure'"
Is there any way that I can structure of the function?
Here's a slight adjustment to get the derivation function working:
test2 <- function(x) D(parse(text=x), "x")
test2("sin(cos(x + y^2))")
# -(cos(cos(x + y^2)) * sin(x + y^2))
test2("x^2")
# 2 * x
test2("x^3")
# 3 * x^2
Use substitute to pass the expression to D:
test2 <- function(e, d) D(substitute(e), deparse(substitute(d)))
test2(sin(cos(x + y^2)), x)
#-(cos(cos(x + y^2)) * sin(x + y^2))
You cannot pass a function to D since it's designed for creating derivatives symbolically, which means it needs expressions containing simple functions known to D.
The function f returns a character vector, and string_der gives the derivative. (I used string manipulation inside since it seems you want to pass an argument.)
string_der <- function(x) {
D(parse(text = x), "x")
}
library(stringr)
f <- function(x) {
str <- "sin(cos(z + y^2))"
str <- str_replace(str, "z", x)
return(str)
}
string_der(f(x = "x"))
# -(cos(cos(x + y^2)) * sin(x + y^2))
I guess following is pretty much Adam Queck has done. It uses quote and let's you pass an object wrapped in quote.
quote_der <- function(x) {
D(eval(x), 'x')
}
f <- function(x) {
qt <- substitute(expression(sin(cos(z + y^2))), list(z = x))
return(qt)
}
quote_der(f(x = quote(x)))
#-(cos(cos(x + y^2)) * sin(x + y^2))
Assuming that:
the function passed as the argument has a one-line body and
if x is not specified it defaults to the name of the first argument to the input function
then we can write
test3 <- function(fun, x = names(formals(fun))[1]) D(body(fun), x)
test3(function(x) x^2)
## 2 * x
I can construct a formula that does what I desire starting with the character versions of terms in a formula, but I'm stumbling in starting with a formula object:
form1 <- Y ~ A + B
form1[-c(1,2)][[1]]
#A + B
Now how to build a formula object that looks like:
Y ~ poly(A, 2) + poly(B, 2) + poly(C, 2)
Or:
Y ~ pspline(A, 4) + pspline(B, 4) + pspline(C, 4)
Seems that it might involve a recursive walk along the RHS but I'm not getting progress. It just occurred to me that I might use
> attr( terms(form1), "term.labels")
[1] "A" "B"
And then use the as.formula(character-expr) approach, but I's sorly of like to see an lapply (RHS_form, somefunc) version of a polyize (or perhaps polymer?) function.
If I borrow some functions I originally wrote here, you could do something like this. First, the helper functions...
extract_rhs_symbols <- function(x) {
as.list(attr(delete.response(terms(x)), "variables"))[-1]
}
symbols_to_formula <- function(x) {
as.call(list(quote(`~`), x))
}
sum_symbols <- function(...) {
Reduce(function(a,b) bquote(.(a)+.(b)), do.call(`c`, list(...), quote=T))
}
transform_terms <- function(x, f) {
symbols_to_formula(sum_symbols(sapply(extract_rhs_symbols(x), function(x) do.call("substitute",list(f, list(x=x))))))
}
And then you can use
update(form1, transform_terms(form1, quote(poly(x, 2))))
# Y ~ poly(A, 2) + poly(B, 2)
update(form1, transform_terms(form1, quote(pspline(x, 4))))
# Y ~ pspline(A, 4) + pspline(B, 4)
There's a formula.tools package that provides various utility functions for working with formulas.
f <- y ~ a + b
rhs(f) # a + b
x <- get.vars(rhs(f)) # "a" "b"
r <- paste(sprintf("poly(%s, 4)", x), collapse=" + ") # "poly(a, 4) + poly(b, 4)"
rhs(f) <- parse(text=r)[[1]]
f # y ~ poly(a, 4) + poly(b, 4)
I have an R formula object:
R> formula.obj <- Y ~ 1 + X + offset(Z)
I want to get rid of offset(Z) and obtain:
R> formula.obj.want <- Y ~ 1 + X
It seems that update function does NOT work in this scenario:
R> update(formula.obj,.~.-offset(Z))
Y ~ X + offset(Z)
Is there way to get formula.obj.want from formula.obj?
You can't do this in update. "-" is not supported for offset formulas http://stat.ethz.ch/R-manual/R-patched/library/stats/html/offset.html
Define another function as u did
You can use the list structure and the language
> formula.obj[[3]] <- quote(1 + X)
> formula.obj
Y ~ 1 + X
> class(formula.obj)
[1] "formula"
Note that I did try update, and it did not want to include the 1
> update(formula.obj, .~ 1 + X)
Y ~ X