[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