raffy cee
raffy cee

Reputation: 51

Basic R Programming

Is there a way to code this simplier than mine?

value = c(0,1,0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0)
first = matrix(value, nrow=6)
second = matrix(rev(first),nrow=6) #reverse vector "value"
output10 = cbind(first,second)
output10    

I am just very curious if there is a simplier way to code this because I find my codes "too rudimentary". Thanks.

Upvotes: 2

Views: 124

Answers (3)

MichaelChirico
MichaelChirico

Reputation: 34763

Assuming your goal is to assign 1 on the off-diagonal elements, the approach that will scale best to massive matrices would be:

N = 100L
M = matrix(0L, N, N)

idx = seq_len(N - 1L)
M[cbind(c(idx, idx+1L), c(idx+1L, idx))] = 1L
M[1:6, 1:6]
#      [,1] [,2] [,3] [,4] [,5] [,6]
# [1,]    0    1    0    0    0    0
# [2,]    1    0    1    0    0    0
# [3,]    0    1    0    1    0    0
# [4,]    0    0    1    0    1    0
# [5,]    0    0    0    1    0    1
# [6,]    0    0    0    0    1    0

This works by using patterns to create the tuples where 1s will be and assigning those only.

In sparse matrix world it would be similar:

library(Matrix)
N = 1e8 # 100,000,000
idx = seq_len(N - 1L)

M = sparseMatrix(c(idx, idx + 1L), c(idx + 1L, idx))
M[1:6, 1:6]
6 x 6 sparse Matrix of class "ngCMatrix"

# [1,] . | . . . .
# [2,] | . | . . .
# [3,] . | . | . .
# [4,] . . | . | .
# [5,] . . . | . |
# [6,] . . . . | .

As a dense matrix, this would be 1e16 integer elements, or 80 petabytes, so M (which is about 1GB) is pretty impressive to keep in memory & declare in a few seconds. Both other approaches here would fail -- row,col, and rev all would create dense vectors.

Upvotes: 0

rawr
rawr

Reputation: 20811

You could create a matrix of 0s and use indexing to put in the 1s where you want

mm <- matrix(0, 6, 6)
mm[col(mm) == row(mm) + 1 | col(mm) == row(mm) - 1] <- 1
mm

#      [,1] [,2] [,3] [,4] [,5] [,6]
# [1,]    0    1    0    0    0    0
# [2,]    1    0    1    0    0    0
# [3,]    0    1    0    1    0    0
# [4,]    0    0    1    0    1    0
# [5,]    0    0    0    1    0    1
# [6,]    0    0    0    0    1    0

Upvotes: 1

AndreyAkinshin
AndreyAkinshin

Reputation: 19071

You can directly create the result matrix from the concatenation of value and rev(value):

value <- c(0,1,0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0)
output10 <- matrix(c(value, rev(value)), nrow=6)

Upvotes: 5

Related Questions