Sorry I couldn't think of a more informative title, but here's my challenge. I have a matrix and I need to add columns in specific places based on parameters described by a vector. For example, if I have the following matrix:
1, 0, 1, 2, 0
0, 0, 1, 1, 1
1, 1, 0, 0, 0
2, 0, 1, 0, 2
but for a particular R package (unmarked), I need to add columns of NA in specific place. I have a vector relating the columns in the matrix:
1, 1, 1, 2, 3
Which indicates that columns 1-3 were from the same sampling period and columns 4 and 5 were from different sampling periods. I need to make the number of columns in the matrix equal the max number from the same sampling period times the number of sampling periods. In this case there are three 1s (max number of any unique value in the vector) and a total of three sampling periods (max number in the vector). So I need a matrix with 9 columns (3 x 3). Specifically, I need to add the new columns of NAs after the 4th and 5th columns. Basically, I just need columns of NAs to be placeholders to have a matrix where the number of observations (each column) is the same (=3) for each of the sample periods (indicated by the number in the vector). This is difficult to describe but in this imaginary example I would want to end up with:
1, 0, 1, 2, NA, NA, 0, NA, NA
0, 0, 1, 1, NA, NA, 1, NA, NA
1, 1, 0, 0, NA, NA, 0, NA, NA
2, 0, 1, 0, NA, NA, 2, NA, NA
this would be described by a vector that looked like:
1, 1, 1, 2, 2, 2, 3, 3, 3
although I don't actually need to produce that vector, just the matrix. Obviously, it was easy to add those columns in this case, but for my data I have a much bigger matrix that will end up with ~200 columns. Plus I will likely have to do this for numerous data sets.
Can anyone help me with a way to code this in R so that I can automate the process of expanding the matrix?
Thanks for any advice or suggestions!
EDIT: to make things a bit more similar to my actual data here is a reproducible matrix and vector similar to my current ones:
m <- matrix(rpois(120*26, 1), nrow = 120, ncol = 26)
v <- c(1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 5, 5, 6, 6, 6, 6, 7)
Assuming m
is the matrix and v
is the vector, you can use something like
t = table(v)
size = dim(m)[1] * max(t) # size of each block based on the longest
matrix(unlist(lapply(names(t), function(i) {
x = m[, v == i] # get the short block
c(x, rep(NA, size - length(x))) # extend it to size
})), dim(m)[1])
To modify the matrix just as you asked assuming the matrix is mat:
nr <- nrow(mat)
nas <- rep(NA, nr)
l <- lapply( 4:ncol(mat), function(x) matrix(c(mat[,x],nas,nas), nrow = nr) )
cbind(mat[,1:3], do.call(cbind,l))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With