On Thu, Nov 15, 2012 at 5:48 PM, Benjamin Ward (ENV) <b.w...@uea.ac.uk> wrote:
> Hi,
>
> I have some values in a list format generated by the following:
> Path_Number <- 0010
> ID.Path <- formatC(0001:Path_Number, width=4, flag=0) # Make vector of ID's.
> No_of_Effectors <- sample(1:550, length(ID.Path), replace=TRUE) # Define 
> Number of Effectors each individual gets.
> Effectors <- split(sample(1:10000, sum(No_of_Effectors), replace=TRUE), 
> rep(ID.Path, No_of_Effectors)) # Generate effectors and dish them out.
> Effectors
>
> And I've written a chunk which is designed to go through each element of the 
> list, and then through each value in the element, and if a conditions is met 
> (in this case if runif(1) is < 0.3, this is simple but may be changed later 
> to be more complex probability criteria based on mutation data from 
> experiment), change the value by 1 in either direction, higher or lower with 
> equal probability. Here it is (I've changed the 0.3 value I mentioned to 0.9, 
> so many values change so it can be easily seen):
>
> l<-0 # Set counter 1 to 0.
> for(i in Effectors){ # Begin loop on list of effectors.
>   l2<-0 # Set counter 2 to 0.
>   l <-l+1 # Increace counter number 1.
>   for(i in Effectors[[l]]){ # Begin loop through all effector values.
>     l2 <-l2+1 # Increace counter number 2.
>     if(runif(1) < 0.9) ifelse(runif(1) <0.5, Effectors[[l]][l2] <- 
> Effectors[[l]][l2]+1, Effectors[[l]][l2] <- Effectors[[l]][l2]-1) # Line 
> which increaces or decreaces the values in the list element (50/50 chance of 
> increace or decreace), if the first IF statement is satisfied.
>   }
> }
>
> Now I don't know if this is the best and most R-ish way of doing this, but it 
> works and I understand it. However I'd like to define a function with this, 
> my attempts so far have been:
>
> Eff.Mutate<-function(){
>   l<-0 # Set counter 1 to 0.
>   for(i in Effectors){ # Begin loop on list of effectors.
>     l2<-0 # Set counter 2 to 0.
>     l <-l+1 # Increace counter number 1.
>     for(i in Effectors[[l]]){ # Begin loop through all effector values.
>       l2 <-l2+1 # Increace counter number 2.
>       if(runif(1) < 0.9) ifelse(runif(1) <0.5, Effectors[[l]][l2] <- 
> Effectors[[l]][l2]+1, Effectors[[l]][l2] <- Effectors[[l]][l2]-1) # Line 
> which increaces or decreaces the values in effvec, if the first IF statement 
> is satisfied.
>     }
>   }
> }
>
> and:
>
> Eff.Mutate2<-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)
>     }
>   }
> }
>
> However if I do either Eff.Mutate() or Eff.Mutate2(Effectors), then neither 
> seems to work; I've seen no differences in the values in the list elements, 
> before and after.
> I can't figure out why it works as a code chunk but if I try to make it a 
> function nothing seems to happen. I'm probably going about making it a 
> function wrong.
>

The problem is that R functions do not operate on objects in the
global environment, where your list lives. They make a copy and
operate on that copy; when the function exists, that local copy is
discarded.

Here's a very simple example:

# Function to change a
change.a.wrong = function(new.a)
{
  a = new.a;
  print(paste("Changed value of a to", a))
}

#Initialize a to 1
a = 1

# change it to 5
change.a.wrong(5)

# but a is still 1!
a
[1] 1

The local copy of a is changed to 5, but discarded and the global copy
whose value is still 1 lives on.

The solution is to return the value of the variable you have changed,
and assign it to the original name. In your case you would define a
function

Eff.Mutate = function(x)
{
  ...your code changes x
  return(x)
}

and you would call it as

effectors.new = Eff.Mutate(effectors)

or so.

HTH,

Peter

______________________________________________
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