Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R type conversion expression() function()

I've been trying to write a program in R that implements Newton's method. I've been mostly successful, but there are two little snags that have been bothering me. Here's my code:

Newton<-function(f,f.,guess){
    #f <- readline(prompt="Function? ")
    #f. <- readline(prompt="Derivative? ")
    #guess <- as.numeric(readline(prompt="Guess? "))
    a <- rep(NA, length=1000)
    a[1] <- guess
    a[2] <- a[1] - f(a[1]) / f.(a[1])
    for(i in 2:length(a)){
        if(a[i] == a[i-1]){
           break
        } 
        else{
           a[i+1] <- a[i] - f(a[i]) / f.(a[i])
        }
    }   
    a <- a[complete.cases(a)]
    return(a)
}
  1. I can't get R to recognize the functions f and f. if I try using readline() to prompt for user input. I get the error "Error in Newton() : could not find function "f."" However, if I comment out the readlines (as above), define f and f. beforehand, then everything works fine.

  2. I've been trying to make R calculate the derivative of a function. The problem is that the class object with which R can take symbolic derivatives is expression(), but I want to take the derivative of a function() and have it give me a function(). In short, I'm having trouble with type conversion between expression() and function().

I have an ugly but effective solution for going from function() to expression(). Given a function f, D(body(f)[[2]],"x") will give the derivative of f. However, this output is an expression(), and I haven't been able to turn it back into a function(). Do I need to use eval() or something? I've tried subsetting, but to no avail. For instance:

g <- expression(sin(x))
g[[1]]
sin(x)
f <- function(x){g[[1]]}
f(0)
sin(x)

when what I want is f(0) = 0 since sin(0) = 0.

EDIT: Thanks all! Here's my new code:

Newton<-function(f,f.,guess){
    g<-readline(prompt="Function? ")
    g<-parse(text=g)
    g.<-D(g,"x")
    f<-function(x){eval(g[[1]])}
    f.<-function(x){eval(g.)}
    guess<-as.numeric(readline(prompt="Guess? "))
    a<-rep(NA, length=1000)
    a[1]<-guess
    a[2]<-a[1]-f(a[1])/f.(a[1])
    for(i in 2:length(a)){
        if(a[i]==a[i-1]){break
        }else{
        a[i+1]<-a[i]-f(a[i])/f.(a[i])
        }
    }   
a<-a[complete.cases(a)]
#a<-a[1:(length(a)-1)]
return(a)
}
like image 535
Viktor Vaughn Avatar asked Jan 13 '12 20:01

Viktor Vaughn


People also ask

How do I convert a datatype in R?

convert() function in R Language is used to compute the data type of a particular data object. It can convert data object to logical, integer, numeric, or factor.

What are type conversion functions?

Type conversion functions allow you to convert an input from one data type to another. Use these functions when you need to change to a specific data type in order to use another function.

How do I convert a string to an expression in R?

Convert a String to an Expression in R Programming – parse() Function. parse() function in R Language is used to convert an object of character class to an object of expression class.


2 Answers

  1. This first problem arises because readline reads in a text string, whereas what you need is an expression. You can use parse() to convert the text string to an expression:

    f <-readline(prompt="Function? ")
    sin(x)
    f
    # [1] "sin(x)"
    
    f <- parse(text = f)
    f
    # expression(sin(x))
    
    g <- D(f, "x")
    g
    # cos(x)
    
  2. To pass in values for the arguments in the function call in the expression (whew!), you can eval() it in an environment containing the supplied values. Nicely, R will allow you to supply those values in a list supplied to the envir= argument of eval():

    > eval(f, envir=list(x=0))
    # [1] 0
    
like image 73
Josh O'Brien Avatar answered Oct 14 '22 17:10

Josh O'Brien


Josh has answered your question

For part 2 you could have used

g <- expression( sin(x) )

g[[1]]
# sin(x)

f <- function(x){ eval( g[[1]] ) }

f(0)
# [1] 0
f(pi/6)
# [1] 0.5
like image 24
Henry Avatar answered Oct 14 '22 16:10

Henry