tbkent
tbkent

Reputation: 63

Sampling and replacing random elements of a vector, conditionally

Suppose I have a vector containing data:

c <- c(1:100)
c[1:75] <- 0
c[76:100] <- 1

What I need to do is select a number of the 0's and turn them into 1's. There are potentially many ways to do this - like if I'm switching 25 of the 0's, it'd be 75 choose 25, so 5.26x10^19 - so I need do it, say, 1000 times randomly. (this is part of a larger model. I'll be using the mean of the results.)

I know (think), that I need to use sample() and a for loop - but how do I select n values randomly among the 0's, then change them to 1's?

Upvotes: 2

Views: 2019

Answers (1)

Gregor Thomas
Gregor Thomas

Reputation: 145755

vec <- c(rep(0, 75), rep(1, 25))

n <- 25
to_change <- sample(which(vec == 0), n)
modified_vec <- vec
modified_vec[to_change] <- 1

Something like this. You could wrap it up in a function.

And you should really do it in a matrix with apply, rather than a for loop.

This small example is easy to see it work:

n_vecs <- 5
vec_length <- 10
n_0 <- 7 # Number of 0's at the start of each vector

vec_mat <- matrix(c(rep(0, n_vecs * n_0), rep(1, n_vecs * (vec_length - n_0))),
                    nrow = vec_length, ncol = n_vecs, byrow = T)

> vec_mat
      [,1] [,2] [,3] [,4] [,5]
 [1,]    0    0    0    0    0
 [2,]    0    0    0    0    0
 [3,]    0    0    0    0    0
 [4,]    0    0    0    0    0
 [5,]    0    0    0    0    0
 [6,]    0    0    0    0    0
 [7,]    0    0    0    0    0
 [8,]    1    1    1    1    1
 [9,]    1    1    1    1    1
[10,]    1    1    1    1    1

change_n_0 <- function(x, n) {
    x_change <- sample(which(x == 0), n)
    x[x_change] <- 1
    return(x)
}

vec_mat <- apply(vec_mat, MARGIN = 2, FUN = change_n_0, n = 2)

> vec_mat
      [,1] [,2] [,3] [,4] [,5]
 [1,]    1    1    0    0    1
 [2,]    0    0    0    1    0
 [3,]    0    0    0    0    0
 [4,]    0    0    0    0    0
 [5,]    0    0    1    0    1
 [6,]    0    1    0    1    0
 [7,]    1    0    1    0    0
 [8,]    1    1    1    1    1
 [9,]    1    1    1    1    1
[10,]    1    1    1    1    1

You can scale up the constants at the beginning as big as you'd like.

Upvotes: 3

Related Questions