Hi, I'm new to R and have a problem with a little test program (see below). Why doesn't <<- in function rk4 assign the new value to y so that it is seen in rktest. I thought that <<- does exactly this. But it seems that I didn't get it right. I would be very appreciative for an explanation of that behaviour of <<-. I know how to write the whole thing so that it works (return the updated y to rktest) but I would like to learn how variable scope in R works. Thanks in advance Rolf ---------------------------------------------------------------------------------------------------------------------- rk4 <- function(x,y,f,h) { n <- length(y) hh <- h*0.5 k1 <- f(x,y) k2 <- f(x,y+k1*hh) k3 <- f(x,y+k2*hh) k4 <- f(x,y+k3*h) y <<- y + h/6.0*(k1 + 2.0*k2 + 2.0*k3 + k4)) } rkf <- function(x,y) { -y } rktest <- function(){ y <- 1.0 x <- 0.0 h <- 0.1 for(i in 1:10) { rk4(x,y,rkf,h) print(y) } } rktest()
[Please try to make sure the code you posted contains no syntax error.] Try:> rktest <- function(){+ rk4 <- function(x,y,f,h) { + n <- length(y) + hh <- h*0.5 + k1 <- f(x,y) + k2 <- f(x,y+k1*hh) + k3 <- f(x,y+k2*hh) + k4 <- f(x,y+k3*h) + y <<- y + h/6.0*(k1 + 2.0*k2 + 2.0*k3 + k4) + } + y <- 1.0 + x <- 0.0 + h <- 0.1 + for(i in 1:10) { + rk4(x,y,rkf,h) + print(y) + } + }> > rktest()[1] 0.9048375 [1] 0.8187309 [1] 0.7408184 [1] 0.6703203 [1] 0.6065309 [1] 0.5488119 [1] 0.4965856 [1] 0.4493293 [1] 0.40657 [1] 0.3678798 You expected `y' in rktest() to be modified by the super-assignment, which is incorrect. In your version, you'll find the super-assignment creating `y' in the global environment, rather than modifying the copy in rktest(). The reason is that the order variables are looked up in rk4() is: 1. within rk4() 2. where rk4() is defined 3. if 2 above is a function, where that function is defined ... eventually: the global environment BTW, I'm not sure if you really meant to do y <<- y + ... because the `y' on the RHS will be the local copy (if exists). Andy> From: Rolf Wester > > Hi, > > I'm new to R and have a problem with a little test program > (see below). > Why doesn't <<- in function rk4 > assign the new value to y so that it is seen in rktest. I > thought that > <<- does exactly this. But it seems that I > didn't get it right. I would be very appreciative for an > explanation of > that behaviour of <<-. I know how to > write the whole thing so that it works (return the updated y > to rktest) > but I would like to learn how variable scope > in R works. > > Thanks in advance > > Rolf > > -------------------------------------------------------------- > -------------------------------------------------------- > > rk4 <- function(x,y,f,h) { > n <- length(y) > hh <- h*0.5 > k1 <- f(x,y) > k2 <- f(x,y+k1*hh) > k3 <- f(x,y+k2*hh) > k4 <- f(x,y+k3*h) > y <<- y + h/6.0*(k1 + 2.0*k2 + 2.0*k3 + k4)) > } > > rkf <- function(x,y) { > -y > } > > rktest <- function(){ > y <- 1.0 > x <- 0.0 > h <- 0.1 > for(i in 1:10) { > rk4(x,y,rkf,h) > print(y) > } > } > > rktest() > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide! > http://www.R-project.org/posting-guide.html > >
Rolf Wester <rolf.wester at ilt.fraunhofer.de> writes:> Hi, > > I'm new to R and have a problem with a little test program (see > below). Why doesn't <<- in function rk4 > assign the new value to y so that it is seen in rktest. I thought that > <<- does exactly this. But it seems that I > didn't get it right. I would be very appreciative for an explanation > of that behaviour of <<-. I know how to > write the whole thing so that it works (return the updated y to > rktest) but I would like to learn how variable scope > in R works.R has lexical scope and rk4() is not lexically scoped in rktest(). I believe that there's a rather thorough discussion of these matters in the FAQ.> rk4 <- function(x,y,f,h) {....> y <<- y + h/6.0*(k1 + 2.0*k2 + 2.0*k3 + k4)) > } > > rkf <- function(x,y) { > -y > } > > rktest <- function(){ > y <- 1.0 > x <- 0.0 > h <- 0.1 > for(i in 1:10) { > rk4(x,y,rkf,h) > print(y) > } > } > > rktest()-- O__ ---- Peter Dalgaard Blegdamsvej 3 c/ /'_ --- Dept. of Biostatistics 2200 Cph. N (*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918 ~~~~~~~~~~ - (p.dalgaard at biostat.ku.dk) FAX: (+45) 35327907
Rolf Wester wrote:> Hi, > > I'm new to R and have a problem with a little test program (see below). > Why doesn't <<- in function rk4The reason is lexical scoping (see FAQ), and I suggest to implement rk4 as function with a return value (see # !!!). BTW there are already a rk4 (and lsoda) functions in the odesolve package. Thomas P. Your example formally corrected: rk4 <- function(x,y,f,h) { n <- length(y) hh <- h*0.5 k1 <- f(x,y) k2 <- f(x,y+k1*hh) k3 <- f(x,y+k2*hh) k4 <- f(x,y+k3*h) y + h/6.0*(k1 + 2.0*k2 + 2.0*k3 + k4) # !!! } rkf <- function(x,y) { -y } rktest <- function(){ y <- 1.0 x <- 0.0 h <- 0.1 for(i in 1:10) { y <- rk4(x,y,rkf,h) # !!! print(y) } } rktest()