Jsukup Jsukup - 2 months ago 8
R Question

Change vector value based on value in same vector

This is probably a similar question to other posted before, but I couldn't find an exact match (please direct me to it if it's already on here).

Anyway, I have a matrix with 19 columns and ~5,000 rows. Each row contains one value between 0.0 and 1 in increments of .1 (so, 0.0, 0.1,0.2...1.0) like thus:

0 0.6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0.5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0.4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
...
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0.9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0.8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0


So the vectors go from 1 to 0.1 before starting over again at 1 and shifted over to the next column. I'd like a function that basically goes from row to row, looks to see if there is a numeric value and then puts 1 minus that value in the next place in the vector. Effectively like this:

0 0.6 0.4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0.5 0.5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0.4 0.6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
...
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0.9 0.1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0.8 0.2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0


I've tried a few things with "apply" or just base recoding but the trick is getting it to run through all ~5,000 rows. Maybe I should approach it by going through the columns?

Answer

Think value and index separately. Indexing in R could be very powerful.

# simulate data. smaller size for simplification
m <- matrix(0, nrow = 200, ncol = 12)
r_indice <- 1:200
c_indice <- rep(2:11, each = 10)
m[cbind(r_indice, c_indice)] <- rep(seq(0.1, 1, by = 0.1), 10)

# find non-zero value indice
value_indice <- which(m !=0, arr.ind = T)
new_value_indice <- value_indice
new_value_indice[, 2] <- new_value_indice[, 2] + 1
m[new_value_indice] <- 1 - m[value_indice]
Comments