Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
502 views
in Technique[技术] by (71.8m points)

r - Extracting off-diagonal slice of large matrix

I've got a large nxn matrix and would like to take off-diagonal slices of varying sizes. For example:

1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6

I'd like an R function which, when given the matrix and "width of diagonal slice" would return an nxn matrix of just those values. So for the matrix above and, say, 3, I'd get:

1 x x x x x
1 2 x x x x
1 2 3 x x x
x 2 3 4 x x
x x 3 4 5 x
x x x 4 5 6

At the moment I'm using (forgive me) a for loop which is incredibly slow:

getDiags<-function(ndiags, cormat){
  resmat=matrix(ncol=ncol(cormat),nrow=nrow(cormat))
  dimnames(resmat)<-dimnames(cormat)
  for(j in 1:ndiags){
    resmat[row(resmat) == col(resmat) + j] <- 
      cormat[row(cormat) == col(cormat) + j]
  }
  return(resmat)
}

I realise that this is a very "un-R" way to go about solving this problem. Is there a better way to do it, probably using diag or lower.tri?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
size <- 6
mat <- matrix(seq_len(size ^ 2), ncol = size)


low <- 0
high <- 3

delta <- rep(seq_len(ncol(mat)), nrow(mat)) - 
    rep(seq_len(nrow(mat)), each = ncol(mat))
#or Ben Bolker's better alternative
delta <- row(mat) - col(mat)
mat[delta < low | delta > high] <- NA
mat

this works with 5000 x 5000 matrices on my machine


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...