Ben,

You can use the sample() function to randomly add -1, 0, or 1 to each 
observation, and control for the probability of mutation at the same time. 
 Then you can use the match() function to make sure that any mutations in 
X are carried through to Y in the same way.  I wrote the function to do 
each list element separately.  So a gene in X[[1] and Y[[1]] will be 
mutated in the same way, but the same gene in X[[2]] and Y[[2]] may be 
mutated in a different way.  Not sure if that is what you want.

Mutate <- function(x, y, prob.mutate=0.9) {
        ux <- unique(c(x, y))
        new.ux <- ux + sample(c(-1, 0, 1), size=length(ux), replace=TRUE, 
prob=c(prob.mutate/2, 1-prob.mutate, prob.mutate/2))
        new.x <- new.ux[match(x, ux)]
        new.y <- new.ux[match(y, ux)]
        list(xm=new.x, ym=new.y)
        }

Effectors <- lapply(seq(X), function(i) Mutate(X[[i]], Y[[i]]))

Jean



"Benjamin Ward (ENV)" <b.w...@uea.ac.uk> wrote on 11/27/2012 10:45:23 AM:
> 
> 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 attemptedthis 
with:
> 
> 
> 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])]
>           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 "}"
> 
> 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@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.

Reply via email to