[R] sas retain statement in R or fitting differene equations in NLS
Berend Hasselman
bhh at xs4all.nl
Thu Mar 8 19:27:58 CET 2012
On 08-03-2012, at 14:50, Journals wrote:
> I wish to fit a dynamical model in R and I am running in a problem that
> requires some of your wisdom to solve. For SAS users I am searching for
> the equivalent of the */retain/ *statement.
>
> For people that want to read complicated explanations to help me:
>
> I have a system of two equations written as difference equations here.
>
> To boil it down. I have a dataframe with three variables y, X1, X2 which
> are measured. Now, I want to estimate a model which says y=
> yhat+epsillon as in standard nonlinear regression. Where yhat is the
> predicted value of y.
>
> yhat can be calculated as follows:
>
> # This code illustrates how I could simulate the expected values of y if
> I knew the values of the parameters tau and b.
> # but in reality I would like to estimate them.
> # code is for illustration of the principles and is not meant to be
> functional!!
> yaux[1]<-0
> b<- a_number # b would have to become estimated by nls or nlme
> tau<- another_number # tau would also be estimated in nls or nlme
> for (t in 2:1000)
> {
> yaux[t+1] <- yaux[t] + (X1-yaux[t])/tau
> yhat[t+1] <- yaux[t+1]*X2[t+1]/(X2[t+1]+b)
> }
>
This can't be correct. When t==2 you are referencing yaux[2] which has no value.
Secondly, you haven't indexed X1 in the equation for yaux[t+1]. Is it X1[t]?
Besides that you don't have to calculate yaux that way.
You can use filter. As in
# Initial value yaux is 0
yaux <- as.vector(filter(a*X1,c(1-a),method="recursive"))
where a = 1/tau and assuming you meant X1[t].
And then you don't need to calculate yhat recursively.
You can do it with
yhat <- yaux * X2/(X2+b)
> Now, my problem is that I do not know the values of /tau/ and /b/ and I
> would like to estimated them by non-linear regression. This is easy in
> the case of /b/ but for /tau /nls (or nlme etc) would have to remember
> the value of /yaux /for the previous observation and I did not find any
> syntactical mean to do that.
>
You could do a non linear regression with
y.rhs <- function(a,b,X1,X2) as.vector(filter(a*X1,c(1-a),method="recursive")) * X2/(X2+b)
nls(y ~ y.rhs(a,b,X1,X2), start=list(a=a,b=b))
where tau=1/a
Here is an example with random data
N <- 500
a <- .4
b <- 1
# generate some random data
set.seed(1)
X1 <- 5*round(runif(N),2)
X2 <- round(runif(N),2)
yaux <- as.vector(filter(a*X1,c(1-a),method="recursive"))
yhat <- yaux * X2/(X2+b)
eps <- runif(N)/2
eps <- eps - mean(eps)
y <- yhat + eps
sum((y-yhat)^2)
# starting values
a <- .6
b <- 2
y.rhs <- function(a,b,X1,X2) as.vector(filter(a*X1,c(1-a),method="recursive")) * X2/(X2+b)
nls(y ~ y.rhs(a,b,X1,X2), start=list(a=a,b=b))
Berend
More information about the R-help
mailing list