I have a, no doubt, simple question. I wish to write a function such that a <- 9 b <- 10 changer _ function(x,y) { if (y>x){ x <<- Y+1}} Of course there are easier ways to accomplish the task above, but I am more interested in how to have the "x <<- Y+1" part of the function to change x in place for purposes of a much larger function. I have been wrestling with various forms of the assign, as.name, deparse, substitute (by now you probably sense a air of desperation) commands, and permuations thereof. These variables will be in a detached data.frame (not shown here). Thanks for your time. Michaell -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html Send "info", "help", or "[un]subscribe" (in the "body", not the subject !) To: r-help-request at stat.math.ethz.ch _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
Michaell Taylor <pols1oh at bestweb.net> writes:> I have a, no doubt, simple question. I wish to write a function such > that > > a <- 9 > b <- 10 > changer _ function(x,y) { if (y>x){ x <<- Y+1}}(something appears to be missing here?)> Of course there are easier ways to accomplish the task above, but I am > more interested in how to have the "x <<- Y+1" part of the function to > change x in place for purposes of a much larger function. > > I have been wrestling with various forms of the assign, as.name, > deparse, substitute (by now you probably sense a air of desperation) > commands, and permuations thereof...although not with sufficient perseverance, I suggest. These matters are tricky and you need to pay close attention to the details, but it pays off in the longer run. I think what you mean is something like this: changer <- function(x,y) { xx <- substitute(x) if (y > x) eval.parent(substitute(x <- foo, list(foo=y + 1, x=xx))) } or changer <- function(x,y) { xx <- deparse(substitute(x)) if (y > x) assign(xx, y + 1, envir=parent.frame()) } The tricky bit is that you cannot substitute the actual argument for x after it gets evaluated for the y > x condition. (Note however that more often that not, this kind of stuff turns out to be just a mental exercise, because there is a better way of doing what you were trying to do originally!) -- 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 -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html Send "info", "help", or "[un]subscribe" (in the "body", not the subject !) To: r-help-request at stat.math.ethz.ch _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
> > Why not tell us what you actually want to do? > There are probably much simpler, more direct ways of doing it, but > given the information above who could tell? > For example, I don't think I have needed to use <<- to overcome any > programming problem that did not involve environments.You are right. Frequently the simplifications don't actually target the problem. The overall issue is that the data.frame data is a collection of monte carlo simulations. the ML data is a most likely estimate of the same series. I want to adjust the Monte carlo simulations so that the most likely fit in the "fat part" of the montecarlo distribution. I do this by assessing the year by year fit and make the adjustments - importantly, the adjustments are saved to "adjustments" for auditing purposes. lagger _ function(X,y,z,l=1) {temp _ c(rep(NA,l),X[-((length(X)-(l-1)):length(X))]) temp[y==min(y)] _ z return(temp)} # X,y,z,l = variable, marker for first obs of scenario (yr), z=prior level value growit _ function(x,y,z) {(x/lagger(x,y,z)) } inrange _ function(v,Y,s,z,mlv,met){ lower _ mean(v[data$yr==Y])-(var(v[data$yr==Y])^.5) upper _ mean(v[data$yr==Y])+(var(v[data$yr==Y])^.5) MLE _ mlv[ML$yr==Y & ML$metcode==met] diffa _ 0 if (MLE<lower) {print('lower') diffa <- lower-MLE v[data$yr==Y] <<- v[data$yr==Y]-diffa} THE PROBLEM AREA if (MLE>upper) {print('higher') diffa <- MLE-upper v[data$yr==Y] <<- v[data$yr==Y]+diffa} THE PROBLEM AREA if (diffa!=0) { v _ growit(v,s,z) adjustment$met _ append(adjustment$met,met) adjustment$sector _ append(adjustment$sector,sector) adjustment$ML _ append(adjustment$ML,MLE) adjustment$lower _ append(adjustment$lower,lower) adjustment$upper _ append(adjustment$upper,upper) adjustment$Var _ append(adjustment$Var,quote(v)) adjustment$diffa _ append(adjustment$diffa,diffa) } } inrange(data$Linv,Y,data$yr,starting.inv,ML$inv,met) THE PROBLEM AREA - marks the location where I would like to save the changes out to the main data stream. Hope this helps. Thanks.> > deparse(substitute(x)), will however, get you the name of the > variable that was supplied as x. > > the following, is a vectorized version of something similar > > > foo <-function(x,y) ifelse(x>y,x,y) > a <- foo(a,b) > > > > > Michaell > > > > > > -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- > > r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html > > Send "info", "help", or "[un]subscribe" > > (in the "body", not the subject !) To: r-help-request at stat.math.ethz.ch > > _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._ > > -- > +---------------------------------------------------------------------------+ > | Robert Gentleman phone : (617) 632-5250 | > | Associate Professor fax: (617) 632-2444 | > | Department of Biostatistics office: M1B28 > | Harvard School of Public Health email: rgentlem at jimmy.dfci.harvard.edu | > +---------------------------------------------------------------------------+-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html Send "info", "help", or "[un]subscribe" (in the "body", not the subject !) To: r-help-request at stat.math.ethz.ch _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
Thanks so very much for your time. I am impressed by R, but tend to think in stata/sas (but I am making progress). I am even more impressed by participants in this list. On Tue, 2002-03-19 at 07:31, Robert Gentleman wrote:> Michaell, > I think this is what you want to do, > lagger <- function(X, y, z, l=1) { > lenX <- length(X) > temp <- c(rep(NA,l), X[-((lenX-(l-1)):lengX)] ) > temp[y==min(y)] <- z > return(temp) > }ah, I guess this change is for a bit more speed and readibility. Thanks.> > growit <- function(x,y,z) (x/lagger(x,y,z)) > > #what's data? it must be a free variable and > #that is not generally a good ideanI am not entirely sure what you mean by "free" variable but it is a data.frame.> > inrange <- function(v, Y, s, z, mlv, met) { > lower <- mean(v[data$yr==Y])-(var(v[data$yr==Y])^.5) > upper <- mean(v[data$yr==Y])+(var(v[data$yr==Y])^.5) > MLE <- mlv[ML$yr==Y & ML$metcode==met] > diffa <- 0 > if (MLE<lower) { > print('lower') > diffa <- lower-MLE > rval <- v[data$yr==Y]-diffa > } > if (MLE>upper) { > print('higher') > diffa <- MLE-upper > rval <- v[data$yr==Y]+diffa > } > if (diffa!=0) { > v <- growit(v,s,z) > adjustment$met <- append(adjustment$met,met) > adjustment$sector <- append(adjustment$sector,sector) > adjustment$ML <- append(adjustment$ML,MLE) > adjustment$lower <- append(adjustment$lower,lower) > adjustment$upper <- append(adjustment$upper,upper) > adjustment$Var <- append(adjustment$Var,quote(v)) > adjustment$diffa <- append(adjustment$diffa,diffa) > } > rval > } > > #note that you assign something > data$Linv[data$yr==Y] <- inrange(data$Linv,Y,data$yr,starting.inv,ML$inv,met) > > Also, why if you pass in data$yr as variable 's' do you not use it? > In lines 1,2,8,11, for example.'s' is passed by inrange to growit. poor planning, but 's' in inrange converts to 'y' in growit.> Why are you changing adjustment and not returning it?a bug that I had not seen yet.> > Basically, you have no need to have a function change anything outside > of its scope. Simply return an object and assign is as needed in the > calling functions (sort of the whole point really). > If you need to return two things use a list. > > return(list(a=1,b=10), for exampleNow THIS is interesting. I had thought that a multiple return would be neat, but didn't realize one could do it. This function was built to change in place values for the data frames data and adjustment with the notion that a multiple return was not possible. Also, because the data is somewhat large, I thought that perhaps an "in place" change to vectors in the data data.frame might be more memory conservative than a "return" sort of arrangement. This probably is not the case. Thanks again. Michaell> > > robert > > -- > +---------------------------------------------------------------------------+ > | Robert Gentleman phone : (617) 632-5250 | > | Associate Professor fax: (617) 632-2444 | > | Department of Biostatistics office: M1B28 > | Harvard School of Public Health email: rgentlem at jimmy.dfci.harvard.edu | > +---------------------------------------------------------------------------+-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html Send "info", "help", or "[un]subscribe" (in the "body", not the subject !) To: r-help-request at stat.math.ethz.ch _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._