2

My question is if there is a way to create two graphs that move one point up or down at a time in a random walk, and there will be a high [synthetic] correlation between them [example: 0.8 in Pearson's correlation]

Thank you

whuber
  • 322,774

1 Answers1

3

As whuber notes in the comments, a version of this can be done using correlated Bernoulli random variables. It is possible to generate correlated Bernoulli random variables and form random walks from this, but the resulting correlation of the larger increments of the random walks are more complicated.

In any case, here is a function you can use to generate correlated Bernoulli random variables (this is taken from my answer to this related question).

rcorrbinom <- function(n, size = 1, prob1, prob2, corr = 0) {

#Check inputs if (!is.numeric(n)) { stop('Error: n must be numeric') } if (length(n) != 1) { stop('Error: n must be a single number') } if (as.integer(n) != n) { stop('Error: n must be a positive integer') } if (n < 1) { stop('Error: n must be a positive integer') } if (!is.numeric(size)) { stop('Error: n must be numeric') } if (length(size) != 1) { stop('Error: n must be a single number') } if (as.integer(size) != size) { stop('Error: n must be a positive integer') } if (size < 1) { stop('Error: n must be a positive integer') } if (!is.numeric(prob1)) { stop('Error: prob1 must be numeric') } if (length(prob1) != 1) { stop('Error: prob1 must be a single number') } if (prob1 < 0) { stop('Error: prob1 must be between 0 and 1') } if (prob1 > 1) { stop('Error: prob1 must be between 0 and 1') } if (!is.numeric(prob2)) { stop('Error: prob2 must be numeric') } if (length(prob2) != 1) { stop('Error: prob2 must be a single number') } if (prob2 < 0) { stop('Error: prob2 must be between 0 and 1') } if (prob2 > 1) { stop('Error: prob2 must be between 0 and 1') } if (!is.numeric(corr)) { stop('Error: corr must be numeric') } if (length(corr) != 1) { stop('Error: corr must be a single number') } if (corr < -1) { stop('Error: corr must be between -1 and 1') } if (corr > 1) { stop('Error: corr must be between -1 and 1') }

#Compute probabilities P00 <- (1-prob1)(1-prob2) + corrsqrt(prob1prob2(1-prob1)*(1-prob2)); P01 <- 1 - prob1 - P00; P10 <- 1 - prob2 - P00; P11 <- P00 + prob1 + prob2 - 1; PROBS <- c(P00, P01, P10, P11) if (min(PROBS) < 0) { stop('Error: corr is not in the allowable range') }

#Generate the output RAND <- array(sample.int(4, size = n*size, replace = TRUE, prob = PROBS), dim = c(n, size)); VALS <- array(0, dim = c(2, n, size)); OUT <- array(0, dim = c(2, n)); for (i in 1:n) { for (j in 1:size) { VALS[1,i,j] <- (RAND[i,j] %in% c(3, 4)); VALS[2,i,j] <- (RAND[i,j] %in% c(2, 4)); } OUT[1, i] <- sum(VALS[1,i,]); OUT[2, i] <- sum(VALS[2,i,]); }

#Give output OUT; }

You can use this to generate two correlated random walks. In the code below I generate correlated random walks $\{ (X_t,Y_t) | t \in \mathbb{R} \}$ using the anchoring point $X_0=Y_0 = 0$ and the correlation value $\rho = 0.4$.

#Set parameters
n    <- 1000
CORR <- 0.4;

#Generate correlated random walks SAMPLE <- rcorrbinom(n = n, prob1 = 0.5, prob2 = 0.5, corr = CORR); WALK1 <- -(1:n) + 2cumsum(SAMPLE[1,]); WALK2 <- -(1:n) + 2cumsum(SAMPLE[2,]); WALKS <- data.frame(Time = 1:n, Walk1 = WALK1, Walk2 = WALK2);

#Plot the random walks library(ggplot2); THEME <- theme(plot.title = element_text(hjust = 0.5, size = 14, face = 'bold'), plot.subtitle = element_text(hjust = 0.5, face = 'bold')); FIGURE <- ggplot(aes(x = Time), data = WALKS) + geom_line(aes(y = Walk1), colour = 'Red') + geom_line(aes(y = Walk2), colour = 'Blue') + THEME + ggtitle('Correlated Random Walks') + ylab('Value');

enter image description here

Ben
  • 124,856