Random walks in R

For some reason I thought it would be an interesting exercise in my programming skills to try and write code to generate random walks in a two-dimensional plane. Turns out this was not super hard, so I wound up having some fun making the code relatively nice.

Below is the function that I made to model a random walk for a specified number of individuals (the argument n.org) and a specified number of time steps (the argument steps). The additional arguments specify the probability of an individual moving left (or p(right) = 1-p(left)) or the probability of moving up (where p(down) = 1-p(up)). The last argument I included to show a plot of all individuals’ paths through time.


random_walk <- function(n.org, steps, left.p = .5, up.p = .5, plot = TRUE){

require(ggplot2)

whereto <- matrix(ncol = 2)

for(x in 1:n.org){
walker <- matrix(c(0,0), nrow = steps+1, ncol = 2, byrow = T)

for(i in 1:steps){
# left/right = 1/0
horizontal <- rbinom(1, 1, left.p)

# distance 2
h.dist <- abs(rnorm(1, 0, 1))

# Horizontal Movement
if(horizontal == 0){
walker[i+1,1] <- walker[i,1] + h.dist
}
if(horizontal == 1){
walker[i+1,1] <- walker[i,1] - h.dist
}

# up/down = 1/0
vertical <- rbinom(1, 1, up.p)

#distance 2
v.dist <- abs(rnorm(1, 0, 1))

# Vertical Movement
if(vertical == 1){
walker[i+1,2] <- walker[i,2] + v.dist
}
if(vertical == 0){
walker[i+1,2] <- walker[i,2] - v.dist
}
}

whereto <- rbind(whereto, walker)
}

id <- rep(1:n.org, each = 1001)
colnames(whereto) <- c("x" , "y")
whereto <- as.data.frame(whereto)
whereto <- cbind(whereto[2:nrow(whereto),], org = factor(id))

if(plot){
require(ggplot2)
p <- ggplot(whereto, aes(x = x, y = y, colour = org))
p <- p + geom_path()
print(p)
}

return(whereto)
}

rw.test <- random_walk(1, 1000, .5, .5)

Running this code gives a 3 column data frame with steps*n.org rows. Each row of the data frame gives the (x, y) position of a given individual (individual number is in the third column). When plot = TRUE, the function will also print out a plot of the path that is taken by each individual (color coded by individual). Note that the plotting part of this function does require ggplot2.

random-walk-2

Each individual in this case starts at (0, 0) and follows a random walk from there.

randowalk2

I have also been playing around with the animation package, so the above gif was created using the saveGIF function and just iteratively creating images with n rows of the data frame. The code I used to generate this is:


require(animation)
ani.options(interval = .25)
saveGIF(
{for(i in seq(2,1001,1)){
gp <- ggplot(rw.test, aes(x=x, y=y, col = org)) + geom_path(alpha = .5)
gp <- gp + geom_point(x=rw.test[i,1], y=rw.test[i,2], col = "red")
print(gp)
}},
movie.name = "randowalk.gif", interval = .25, nmax =1000, ani.width = 600, ani.height = 600,
outdir = getwd()
)

It was not super hard to write, but it did take me a while before things worked properly.


rw.test <- random_walk(10, 1000, .5, .5)
ind10.1 <- rw.test
rw.test <- random_walk(10, 1000, .5, .5)
ind10.2 <- rw.test
rw.test <- random_walk(10, 1000, .5, .5)
ind10.3 <- rw.test
rw.test <- random_walk(10, 1000, .5, .5)
ind10.4 <- rw.test

ind10.1 <- cbind(ind10.1, group = factor("gr1"))
ind10.2 <- cbind(ind10.2, group = factor("gr2"))
ind10.3 <- cbind(ind10.3, group = factor("gr3"))
ind10.4 <- cbind(ind10.4, group = factor("gr4"))

fourgrp <- rbind(ind10.1, ind10.2, ind10.3, ind10.4)

ggplot(fourgrp, aes(x=x, y=y, col = org)) + geom_path() +facet_wrap(facets = ~group, nrow = 2, ncol = 2)

The above code will generate four examples of the random walk with 10 individuals each. The plot then looks like:

Four runs of the random walk with 10 individuals each

Four runs of the random walk with 10 individuals each

Messing around with some of the animation functions in R (the animation package) again you can watch multiple individual randomly walk around the plane…

randowalk-multi

Well now I have committed to trying to do more with this, so I will be posting more about this kind of random walk stuff in the future. My plan is to (1) make the code better, more modular and more versatile, and (2) build in interactions between individuals. I think that (1) is important because it is how I become a better programmer, but the second part of the plan I find most interesting because species interactions is what I study, and I would like to find a way to incorporate this kind of thing into my research.

 

Advertisements
This entry was posted in Coding, Research and tagged , , , . Bookmark the permalink.

4 Responses to Random walks in R

  1. Ub says:

    Having trouble running this code. Also, can this be expanded to two-dimensions?

    • Ub says:

      Sorry, can a set space be set to partially set a constraint on the movement?

      • Jon Borrelli says:

        There is no reason why you couldn’t do that. My first thought would be to enclose the movement section of the function in an `if` statement and if the whereto object lands in the constrained section, have it rerun the step selection (could do something similar with a `while` loop, and have the simulation continue only when movement is not within the constrained section.

    • Jon Borrelli says:

      Which part does not seem to be working (are you getting an error message at any specific point)? As it stands this is a two-dimensional random walk, but you could presumably add n-dimensions by turning `walker` into an n-column matrix, and adding another set of “Movement” code like the Vertical or Horizontal movement section in the random_walk function.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s