There must an elegant way to do this but I can't figure out so:
Columns are probabilities from 1 to 0 going right
Rows are probabilities from 0 to 1 going down
This kludgy code produces see the desired result (but I want to do it with a much larger matrix than this):
# Vector entries are rowname - colname, if >= 0
#
rb0 <- c(NA,NA,NA,NA,NA,NA,NA,NA,NA,NA, 0)
rb1 <- c(NA,NA,NA,NA,NA,NA,NA,NA,NA, 0,.1)
rb2 <- c(NA,NA,NA,NA,NA,NA,NA,NA, 0,.1,.2)
rb3 <- c(NA,NA,NA,NA,NA,NA,NA, 0,.1,.2,.3)
rb4 <- c(NA,NA,NA,NA,NA,NA, 0,.1,.2,.3,.4)
rb5 <- c(NA,NA,NA,NA,NA, 0,.1,.2,.3,.4,.5)
rb6 <- c(NA,NA,NA,NA, 0,.1,.2,.3,.4,.5,.6)
rb7 <- c(NA,NA,NA, 0,.1,.2,.3,.4,.5,.6,.7)
rb8 <- c(NA,NA, 0,.1,.2,.3,.4,.5,.6,.7,.8)
rb9 <- c(NA, 0,.1,.2,.3,.4,.5,.6,.7,.8,.9)
rb10 <- c( 0,.1,.2,.3,.4,.5,.6,.7,.8,.9,1 )
indbias <- rbind(rb0,rb1,rb2,rb3,rb4,rb5,rb6,rb7,rb8,rb9,rb10)
colnames(indbias) <- seq(1,0,by=-.1)
rownames(indbias) <- seq(0,1,by=.1)
indbias
Thanks!
An atomic (upper or lower) triangular matrix is a special form of unitriangular matrix, where all of the off-diagonal elements are zero, except for the entries in a single column. Such a matrix is also called a Frobenius matrix, a Gauss matrix, or a Gauss transformation matrix.
To create an upper triangular matrix using vector elements, we can first create the matrix with appropriate number of columns and rows then take the transpose of that matrix. After that we will assign the lower triangular matrix elements to 0.
In other words, a square matrix is upper triangular if all its entries below the main diagonal are zero. Example of a 2 × 2 upper triangular matrix: A square matrix with elements sij = 0 for j > i is termed lower triangular matrix.
mat <- matrix(NA, 10,10)
mat[row(mat)+col(mat) >=11] <- (row(mat)+col(mat) -11)[row(mat)+col(mat)>=11]/10
mat
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] NA NA NA NA NA NA NA NA NA 0.0
[2,] NA NA NA NA NA NA NA NA 0.0 0.1
[3,] NA NA NA NA NA NA NA 0.0 0.1 0.2
[4,] NA NA NA NA NA NA 0.0 0.1 0.2 0.3
[5,] NA NA NA NA NA 0.0 0.1 0.2 0.3 0.4
[6,] NA NA NA NA 0.0 0.1 0.2 0.3 0.4 0.5
[7,] NA NA NA 0.0 0.1 0.2 0.3 0.4 0.5 0.6
[8,] NA NA 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7
[9,] NA 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8
[10,] 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9
I think this will be much faster than a plyr solution and I happen to think it is easier to comprehend. It basically sets up a test for the entries that are in the lower right hand "triangle" and then divides the results of that "test" matrix bu 10. You can look at the test matrix with this code:
row(mat)+col(mat) -11
Edit: I thought it possible that making the matrix once as sebastian-c illustrated and then doing a single test to do the NA setting might be faster ( with one third the number of calls to row
and col
) but it appears to be only one third as fast. It looks like the two seq calls take more time than the extra :
mat <- round(outer(seq(-0.5, 0.5, 0.1), seq(-0.5, 0.5, 0.1), `+`), 1)
is.na(mat) <- row(mat)+col(mat) <= 11
mat
I did find another solution based on the little known embed
function:
mat <- embed(seq(-1,1, by=0.1), 11 )[,11:1]
is.na(mat) <- row(mat)+col(mat) <= 11
Although it is 50% faster than the new solution, it is still slower than the original.
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