[R] How to do a backward calculation for each record in a dataset

Berend Hasselman bhh at xs4all.nl
Tue Feb 19 16:51:50 CET 2013


On 19-02-2013, at 09:55, Prakasit Singkateera <asltjoey.rsoft at gmail.com> wrote:

> Hi everyone,
> 
> From your helps of giving me several ideas, eventually I can solve the posted problem. Here is the R code. It can be done by applying the uniroot.all to the data frame together with the proper form of equation (slightly modification of the original equation).
> 
> #Generate the sample data frame
> customer.name = c("John","Mike","Peter")
> product = c("Toothpaste","Toothpaste","Toothpaste")
> cost = c(30,45,40)
> mydata = data.frame(customer.name,product,cost)
> 
> #Original cost function - not used
> #fcost = function(orders) 3.40 + (1.20 * orders^2)
> 
> #Slightly modification of the cost function to be a proper form for root finding
> #This is basically to set ==> 3.40 + (1.20 * orders^2) - fcost = 0
> f.to.findroot = function(orders,fcost) 3.40 + (1.20 * orders^2) - fcost
> 
> #Using rootSolve package which contains uniroot.all function
> library(rootSolve)
> 
> #Using plyr package which contains adply function
> library(plyr)
> 
> #Use uniroot function to find the 'orders' variable (from the f.to.findroot function) for each customer and put it into no.of.orders column in mysolution data frame
> #Replace 'fcost' with 'cost' column from mydata
> #Interval of 0 to 1,000 is to make the f.to.findroot function have both negative and positive sign, otherwise uniroot.all will give an error
> mysolution = data.frame(adply(mydata, 1, summarize, no.of.orders = uniroot.all(f.to.findroot,interval = c(0,1000),fcost=cost)))
> mysolution
> 
> #Remove the redundant mydata as mysolution it is an extended version of mydata
> rm(mydata)
> 
> #Note uniroot.all can be used for both linear (e.g.orders^1) and non-linear (e.g.orders^2) equations.


1. You don't need rootSolve. uniroot is sufficient in your case. You don't have multiple roots for each element of cost.

2. You are now storing more information than you require into the resulting dataframe. Use uniroot(…)$root to store only the root of the equation.

3. you don't need plyr. You can do it like this

mysolution <- within(mydata, 
    no.of.orders <- sapply(seq_len(length(cost)),function(k) uniroot(f.to.findroot,interval = c(0,1000),fcost=cost[k])$root )
)
# for printing the dataframe

mysolution

Berend



More information about the R-help mailing list