I run WolframAlpha through R
Wolfram Alpha API from R
My problem is, that I need to convert wolfram output to R expression.
I have added "*" where it's needed, there's another issue - converting of goniometric functions.
Example:
I have: cos^3(5 + 2*x)
I need to get: (cos(5 + 2*x))^3
Could somebody give me a hint how to achieve the expression? Or is there any package for conversion? Or does somebody suggest any other way?
SOLUTION by #G. Grothendieck
sub("(sin|cos|tan)\\^(\\(?-?\\d+\\)?)", "(function(x) \\1(x)^\\2)", 'cos^3(5 + 2*x)')
Define a function called cos^3, insert backticks into the original string around it and evaluate.
`cos^3` <- function(x) cos(x)^3
s <- sub("cos^3", "`cos^3`", input_string, fixed = TRUE) # `cos^3`(5 + 2*x)
x <- .5 # test value for x
eval(parse(text = s))
## [1] 0.8852069
This could be generalized a bit if need be like this:
input_string <- "cos^(3)(5+2*x)"
sub("(sin|cos|tan)\\^(\\(?-?\\d+\\)?)", "(function(x) \\1(x)^\\2)", input_string)
## [1] "(function(x) cos(x)^(3))(5+2*x)"
I think that you have the original formula as a string and want to evaluate it in R (with the modified syntax). You can change the formula using sub and then evaluate it using parse and eval.
F1 = "cos^3(5 + 2*x)"
F2 = sub("(.*)(\\^\\d)(.*)", "\\1\\3\\2", F1)
F2
[1] "cos(5 + 2*x)^3"
x = 1:4
eval(parse(text=F2))
[1] 4.284944e-01 -7.563824e-01 8.668527e-08 7.472458e-01
Here's a solution to your specific case, which should help getting started on a more general solution (this will work for strings of the form 'cos^X(Y)' where X is some digits and Y is an arithmetic expression):
input_string <- 'cos^3(5 + 2*x)'
desired_output_string <- '(cos(5 + 2*x))^3'
convert_string <- function(s){
return(gsub('(cos)(\\^\\d+)(\\([a-z0-9+* ]+\\))', '(\\1\\3)\\2', s))
}
output_string <- convert_string(input_string)
if (output_string == desired_output_string){
message('the output matches!')
} else { message('try again </3') }
And then if you need to actually evaluate the string, you can use eval(parse(text=output_string)), making sure that all variables it contains have values:
x <- 5
eval(parse(text=output_string))
## -0.4384354
Related
I am new to R and programming in general and am trying to write a very basic function where the input is 2 numbers and a selection from one of 3 operations. The output is supposed to be the result of a further calculation (divide the result of the input by 3*pi) and then a character string to confirm what operation was selected/performed. I want the default operation to be addition.
I've read up a little on the switch function and if... else type statements but not sure what is the most efficient way to achieve what I am trying to do and so far I haven't been able to get anything to work anyway. I seem to be getting a massive matrix as the output or an error to say I can't return multiple arguments in my current attempt. Can someone help with where I am going wrong? Thank you in advance.
basiccalc <- function(x, y, operation = addition){
addition <- x + y
subtraction <- x - y
multiplication <- x * y
calculation <- operation/(3*pi)
return(calculation, "operation")
}
switch would be useful
basiccalc <- function(x, y, operation = addition) {
operation <- deparse(substitute(operation))
op <- switch(operation,
addition = x + y,
subtraction = x - y,
multiplication = x * y)
return(op/(3 *pi))
}
-testing
> basiccalc(3, 5)
[1] 0.8488264
> 8/(3 * pi)
[1] 0.8488264
> basiccalc(3, 5, operation = subtraction)
[1] -0.2122066
> (3- 5)/(3 * pi)
[1] -0.2122066
I need a function created by a list of commands to fully evaluate so that it is identical to the "manual" version of the function.
Background: I am using ScaleR functions in Microsoft R Server and need to apply a set of transformations as a function. ScaleR is very picky about needing to be passed a function that is phrased exactly as specified below:
functionThatWorks <- function(data) {
data$marital_status_p1_ismarried <- impute(data$marital_status_p1_ismarried)
return(data)
}
I have a function that creates this list of transformations (and hundreds more, hence the need to functionalize its writing).
transformList <- list ("data$ismarried <- impute(data$ismarried)",
"data$issingle <- impute(data$issingle)")
This line outputs the evaluated string that I want to the console, but I am unaware of a way to move it from console output to being used in a function:
cat(noquote(unlist(bquote( .(noquote(transformList[1]))))))
I need to evaluate functionIWant so that it is identical to functionThatWorks.
functionIWant <- function(data){
eval( cat(noquote(unlist(bquote( .(noquote(transformList[1])))))) )
return(data)
}
identical(functionThatWorks, functionIWant)
EDIT: Adding in the answer based on #dww 's code. It works well in ScaleR. It is identical, minus meaningless spacing.
functionIWant <- function(){}
formals(functionIWant) <- alist(data=NULL)
functionIWant.text <- parse(text = c(
paste( bquote( .(noquote(transformList[1]))), ";", "return(data)\n")
))
body(functionIWant) <- as.call(c(as.name("{"), functionIWant.text))
Maybe something like this?
# 1st define a 'hard-coded' function
f1 <- function (x = 2)
{
y <- x + 1
y^2
}
f1(3)
# [1] 16
# now create a similar function from a character vector
f2 <- function(){}
formals(f2) <- alist(x=2)
f2.text <- parse(text = c('y <- x + 1', 'y^2'))
body(f2) <- as.call(c(as.name("{"), f2.text))
f2(3)
# [1] 16
I want to create an overloaded function that behaves differently given the arguments provided. For this, I need to check if the argument given is an existing object (e.g. data frame, list, integer) or an abstract formula (e.g. a + b, 2 * 4, y ~ x + y etc.). Below I paste what I would like it to recognize:
df <- data.frame(a, b)
f(df) # data.frame
f(data.frame(a, b)) # data frame
f(a + b) # expression
f("a + b") # character
f(2 * 2 + 7) # expression
f(I(2 * 2)) # integer
Is it possible to construct such a function? How? Unfortunately I wasn't able to find any references on the web or in the books on R programming I know.
The general way of overloading functions in R would be something like this:
f <- function(x) UseMethod("f")
f.default <- function(x) eval(substitute(x))
f.data.frame <- function(x) print("data frame")
It gives:
> f(df)
[1] "data frame"
> f(2 + 2)
[1] 4
> f(list(a, b))
[[1]]
[1] 1
[[2]]
[1] 2
So the problem with doing it like this is that I would have to name all the possible other data types rather than checking if x is an expression.
The same is with using:
f2 <- function(x) typeof(substitute(x))
because it evaluates function calls and expressions in the same manner:
> f2(2 + 2)
[1] "language"
> f2(df)
[1] "symbol"
> f2(data.frame(a, b))
[1] "language"
while I would like it to differentiate between list(a, b) and 2 + 2, because the first one is a list, and the second one is an expression.
I know that it would be easy with a classic R formula that is easily recognizable by R, but is it possible with different input?
Thanks!
It is the principle of object oriented langage in R. You should learn a bit more about it here:
https://www.stat.auckland.ac.nz/~stat782/downloads/08-Objects.pdf
http://brainimaging.waisman.wisc.edu/~perlman/R/A1%20Introduction%20to%20object-oriented%20programming.pdf
There are two types of objects in R: S3 and S4. S3 objects are easier to implement and more flexible. Their use is sufficient for what you want to do. You can use S3 generic functions.
I strongly advise you to learn more about these S3 and S4 classes, but to make it short, you can just look at the class of parameter you give to function f. This can be done thanks to function class.
You can separate your function f in different cases:
f <- function(a){
if (class(a) == 'data.frame'){
# do things...
}
else if (class(a) == 'formula'){
# do things...
}
else if (class(a) == 'integer'){
# do things...
}
else {
stop("Class no supported")
}
}
OK, it seems I tried to complicate it in a greater extent than I had to. The simple answer is just:
if (tryCatch(is.data.frame(x), error=function(z) FALSE)) {
# here do stuff with a data.frame
} else {
# here check the expression using some regular expressions etc.
}
I have a vector of a binary string:
a<-c(0,0,0,1,0,1)
I would like to convert this vector into decimal.
I tried using the compositions package and the unbinary() function, however, this solution and also most others that I have found on this site require g-adic string as input argument.
My question is how can I convert a vector rather than a string to decimal?
to illustrate the problem:
library(compositions)
unbinary("000101")
[1] 5
This gives the correct solution, but:
unbinary(a)
unbinary("a")
unbinary(toString(a))
produces NA.
You could try this function
bitsToInt<-function(x) {
packBits(rev(c(rep(FALSE, 32-length(x)%%32), as.logical(x))), "integer")
}
a <- c(0,0,0,1,0,1)
bitsToInt(a)
# [1] 5
here we skip the character conversion. This only uses base functions.
It is likely that
unbinary(paste(a, collapse=""))
would have worked should you still want to use that function.
There is a one-liner solution:
Reduce(function(x,y) x*2+y, a)
Explanation:
Expanding the application of Reduce results in something like:
Reduce(function(x,y) x*2+y, c(0,1,0,1,0)) = (((0*2 + 1)*2 + 0)*2 + 1)*2 + 0 = 10
With each new bit coming next, we double the so far accumulated value and add afterwards the next bit to it.
Please also see the description of Reduce() function.
If you'd like to stick to using compositions, just convert your vector to a string:
library(compositions)
a <- c(0,0,0,1,0,1)
achar <- paste(a,collapse="")
unbinary(achar)
[1] 5
This function will do the trick.
bintodec <- function(y) {
# find the decimal number corresponding to binary sequence 'y'
if (! (all(y %in% c(0,1)))) stop("not a binary sequence")
res <- sum(y*2^((length(y):1) - 1))
return(res)
}
I want to use information from a field and include it in a R function, e.g.:
data #name of the data.frame with only one raw
"(if(nclusters>0){OptmizationInputs[3,3]*beta[1]}else{0})" # this is the raw
If I want to use this information inside a function how could I do it?
Another example:
A=c('x^2')
B=function (x) A
B(2)
"x^2" # this is the return. I would like to have the return something like 2^2=4.
Use body<- and parse
A <- 'x^2'
B <- function(x) {}
body(B) <- parse(text = A)
B(3)
## [1] 9
There are more ideas here
Another option using plyr:
A <- 'x^2'
library(plyr)
body(B) <- as.quoted(A)[[1]]
> B(5)
[1] 25
A <- "x^2"; x <- 2
BB <- function(z){ print( as.expression(do.call("substitute",
list( parse(text=A)[[1]], list(x=eval(x) ) )))[[1]] );
cat( "is equal to ", eval(parse(text=A)))
}
BB(2)
#2^2
#is equal to 4
Managing expressions in R is very weird. substitute refuses to evaluate its first argument so you need to use do.call to allow the evaluation to occur before the substitution. Furthermore the printed representation of the expressions hides their underlying representation. Try removing the fairly cryptic (to my way of thinking) [[1]] after the as.expression(.) result.