public
Created

Modifying select off-diagonal items in a matrix

  • Download Gist
off_diagonal.R
R
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
# A method for modifying only select off-diagonal items in a matrix
# From "Thierry" and "Ben Bolker"
# At http://stackoverflow.com/a/11759744/479554
 
# A sample matrix
size <- 6
mat <- matrix(seq_len(size ^ 2), ncol = size)
print(mat)
 
# A companion matrix that indicates how "off" a diagonal is:
delta <- row(mat) - col(mat)
print(delta)
 
# Set these to select on the "delta" matrix
low <- 0
high <- 3
 
# Operate on the "mat" matrix
mat[delta < low | delta > high] <- NA
print(mat)
 
# Another example:
mat <- matrix(seq_len(size ^ 2), ncol = size)
mat <- mat * 0
print(mat) # All zeros
 
mat[abs(delta) == 1] <- 1
print(mat) # Ones on the "just off-diagonal."
 
###############
# Application #
###############
 
# To see year-to-year correlation of a set of observations
countryByYear <- matrix(rnorm(500), ncol = 20)
# Replace with numbers that actually have a relationship:
for(ii in 2:ncol(countryByYear)){
countryByYear[, ii] <- countryByYear[, ii-1] + rnorm(nrow(countryByYear))
}
 
colnames(countryByYear) <- paste("year", (2012-ncol(countryByYear)+1):2012, sep = "") # Years
rownames(countryByYear) <- LETTERS[1:nrow(countryByYear)]
 
# Correlations across all years
yearToYearCorrelation <- cor(countryByYear, use = "pair")
print(yearToYearCorrelation)
plot(density(yearToYearCorrelation, na.rm = T))
text(yearToYearCorrelation, 0, "|", col = "GRAY", cex = 1/2)
 
# The delta matrix, which does all of the work for us
delta <- row(yearToYearCorrelation) - col(yearToYearCorrelation)
print(delta)
 
# Correlations between consecutive years only:
yearToYearCorrelation[abs(delta) != 1] <- NA
print(yearToYearCorrelation)
text(yearToYearCorrelation, 0, "|", col = "RED")
# These are generally much higher correlations, naturally

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.