lundi 15 juin 2020

Random values repeat when iterated through purrr:map

I am trying to generate a "fake" data set of spatially limited random walks, i.e., at each timestep, the individual will randomly move an arbitrary distance x and y, but these values need to be constrained to my arena (xlim and ylim)--I don't particularly care what happens (reflection or follow the wall) when the individual hits an edge, but they can't go past the edge.

All the code runs and the function "walker" gives new and different values each time it is separately run, but when I put it through a purrr::map, the values are just repeated for each individual.

I have cobbled this together from a few sources and I'm sure it could be streamlined substantially--eventually, I'll want n.times to be much greater (and the eventual goal will be to calculate the amount of time*# individuals visiting particular grid squares), but step one is to get the individuals to have different movement records!

library(tidyverse)
n.times<-10
OUT <-data.frame(x.a = vector("numeric", n.times),y.a = vector("numeric", n.times))

walker <- function(n.times,
                   xlim=c(0,100),
                   ylim=c(0,30),
                   start=c(0,0),
                   stepsize=c(1,1)) {
  ## extract starting point
  x <- start[1]
  y <- start[2]
  for (i in 1:n.times) {
    repeat {
      ## pick jump sizes
      xi <- stepsize[1]*sample(rnorm(n = n.times, mean = 0, sd = .5),1)
      yi <- stepsize[2]*sample(rnorm(n = n.times, mean = 0, sd = .5),1)
      ## new candidate locations
      newx <- x+xi
      newy <- y+yi
      ## IF new locations are within bounds, then
      ##    break out of the repeat{} loop (otherwise
      ##    try again)
      if (newx>xlim[1] && newx<xlim[2] &&
          newy>ylim[1] && newy<ylim[2]) break
    }
    ## set new location to candidate location
    x <- newx
    y <- newy
    OUT[i,"x.a"] <-x
    OUT[i, "y.a"] <-y
  }
  return(OUT)
}


#generate fake fish
fish<-data.frame(fish=as.character(letters[1:10]))

#apply walker to fake fish
fishmoves <- fish %>% 
  mutate(data= map(.,~walker(10))) %>% 
  unnest(data)



Aucun commentaire:

Enregistrer un commentaire