[R] Stuck trying to modify a function

Milan Bouchet-Valat nalimilan at club.fr
Tue Nov 27 22:51:56 CET 2012


Le mardi 27 novembre 2012 à 16:45 +0000, Benjamin Ward (ENV) a écrit :
> Hi,
> 
> I have the following data:
> 
> Path_Number <- 5
> ID.Path <- c(1:Path_Number) # Make vector of ID's.
> No_of_X <- sample(50:550, length(ID.Path), replace=TRUE) #
> X <- split(sample(1:10000, sum(No_of_X), replace=TRUE), rep(ID.Path,
> No_of_X))
> Y <- lapply(X,function(x) sample(x, round(runif(1, min=10, max=50))))
> 
> X and Y are both lists, and I've made the following function to work
> on that data as part of a simulation I'm building:
> 
> Mutate<-function(x){
>   l<-0
>   for(i in x){
>     l2<-0
>     l<-l+1
>     for(i in x[[l]]){
>       l2<-l2+1
>       if(runif(1) < 0.9) ifelse(runif(1) <0.5, x[[l]][l2] <-
> x[[l]][l2]+1, x[[l]][l2] <- x[[l]][l2]-1)
>     }
>   }
>   return(x)
> }
> 
> I call this with Effectors<-Mutate(X)
> The function is designed to alter the values of each element in X by
> either + or - 1 (50:50 chance wether + or -). However Y, elements of
> which are a subset of the corresponding elements of X, need to be
> consistent i.e. if a value in X is changed, and that value is part of
> the Y subset, then the value in Y also needs to be changed. however,
> since Y is a smaller subset it will not be indexed the same. My idea
> was to include in the function an if statement that checks if Y
> contains the value to be changed, removes it, and then after the value
> in X is changed, put the new value in Y. I attempted this with:
You should really read about vectorizing operations: you can most likely
get the same results in R using only a few lines, with a much better
performance. runif(length(x)) will directly give you a vector of the
needed length, and you can add or subtract 1 from x in one line:

new.x <- ifelse(runif(length(x)) > .5, x + 1, x - 1)
y[match(x, y, nomatch=0)] <- new.x
y <- ifelse(y %in% x, new.x[match(y, x)], y)
x <- new.x

This is of course a proof of concept, I'm not sure this is really what
you asked for. See below for some debugging of your code.

> 
> 
> Mutate<-function(x,y){
>   l<-0
>   for(i in x){
>     l2<-0
>     l<-l+1
>     for(i in x[[l]]){
>       l2<-l2+1
>       if(runif(1) < 0.9){
>         if(x[[l]][l2] %in% y[[l]] == TRUE){
>           y[[l]]<-[which(y[[l]]!=x[[l]][l2])]
Bug is here:       ^

You should specify an object to index.

>           if(runif(1) <0.5){
>             x[[l]][l2] <- x[[l]][l2]+1
>             y[[l]]<-append(x[[l]][l2])
>           }else{
>             x[[l]][l2] <- x[[l]][l2]-1
>             y[[l]]<-append(x[[l]][l2])
>           }
>         }
>         ifelse(runif(1) <0.5, x[[l]][l2] <- x[[l]][l2]+1, x[[l]][l2]
> <- x[[l]][l2]-1)
>       }
>     }
>   }
>   return(list(x,y))
> }
> 
> Bit of an eyesore so I've put the altered stuff in bold. I've
> basically taken what the ifelse statement does in the first function,
> (which is still there and run if Y does not contain the X value being
> altered) and broken it down into an if and an else segment with
> multiple operations in curly braces to accommodate the extra actions
> needed to alter Y as well as X. This was all I could think of to keep
> changes between the two "in sync", however this does not work when I
> try to load the function into workspace:
> 
> Error: unexpected '}' in "}"
You should have copied the full output. This is only the last error
message: once an error happens, the whole syntax is broken and every
bracket can trigger an error. Only by looking at the first error you can
understand what's the problem.


Regards

> I hope someone can point out what it is I've done that isn't working,
> or a better way to do this.
> 
> Best Wishes,
> 
> Ben W.
> 
> UEA (ENV) & The Sainsbury Laboratory.
> 
> 	[[alternative HTML version deleted]]
> 
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.




More information about the R-help mailing list