简体   繁体   中英

Moving from a vector to a matrix in R

I have a list of numbers from 1 to 105. I want to move to a lower triangle matrix with diagonal values. However, i do not want this matrix to fill by row, instead I want the following pattern:

在此处输入图片说明

The number in this matrix refer to the elements from the list (x) that I would want to see in the matrix. So for example, number 64 from the my list should be at the bottom left corner in the matrix.

The existing functions (like lower.tri or matrix(x, byrow=TRUE) dont seem to work here, so I am kind of lost in how to approach this.

x <- c(1:105)

EDIT:

Notice that the matrix in the image has "quirks". These are best illustrated by looking at the column 6 and column 7. Values in the 7th Row go from 27 to 70, in the 8th row from 33 to 71 and so forth. Similarly, the thing happens between column 12 and 13, where values in 13 row go from 96 to 103 and 102 to 104 in the 14 row.

EDIT2:

from comment: The only real rule that i can think of is that after each 6 columns the "weirdness" will occur. With 13x13 matrix instead of 70 it will be 64, with 12x12 it will be 58, and so forth, so it decreases by 6. With 14x14 matrix, there's obviously 14 columns, so the column break will happen twice, after the 6th columns, and after 12th column. With a 19x19 matrix, we'll have the column break occurring three times - after 6th, 12th, and 18th. I bring this up because the unusual values will start after each column break

Edit: Automated Way

Here is a function that should take care of what you are asking for...

code_matrix <- function(p, change_col = 6) {
  # we will create the transpose of the desired matrix first
  # this handles the row wise assignment

  # initialize your matrix
  m <- matrix(0, p, p)

  # create a logical upper triangular to track where we will put values
  a <- matrix(T, p, p)
  a[lower.tri(a)] <- F

  # tracks what the last number from the prior block was
  end_num <- 0

  # how many blocks of columns to divide things into based on the rule
  m_blocks <- 1:ceiling(p / change_col)

  # loop through each of the blocks
  for (i in m_blocks) {

    # calculate the start and end rows in the block
    start_row <- (i - 1) * change_col + 1
    end_row <- min(start_row + (change_col - 1), p)

    # create the sequence of numbers
    v <- end_num + 1:sum(a[start_row:end_row,])

    # store the sequence back into the matrix by using the logical matrix
    m[start_row:end_row,][a[start_row:end_row,]] <- v

    # increase the tracker  
    end_num <- max(v)
  }

  return(t(m))
}

Giving it a test...

> code_matrix(14)

      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14]
 [1,]    1    0    0    0    0    0    0    0    0     0     0     0     0     0
 [2,]    2    3    0    0    0    0    0    0    0     0     0     0     0     0
 [3,]    4    5    6    0    0    0    0    0    0     0     0     0     0     0
 [4,]    7    8    9   10    0    0    0    0    0     0     0     0     0     0
 [5,]   11   12   13   14   15    0    0    0    0     0     0     0     0     0
 [6,]   16   17   18   19   20   21    0    0    0     0     0     0     0     0
 [7,]   22   23   24   25   26   27   70    0    0     0     0     0     0     0
 [8,]   28   29   30   31   32   33   71   72    0     0     0     0     0     0
 [9,]   34   35   36   37   38   39   73   74   75     0     0     0     0     0
[10,]   40   41   42   43   44   45   76   77   78    79     0     0     0     0
[11,]   46   47   48   49   50   51   80   81   82    83    84     0     0     0
[12,]   52   53   54   55   56   57   85   86   87    88    89    90     0     0
[13,]   58   59   60   61   62   63   91   92   93    94    95    96   103     0
[14,]   64   65   66   67   68   69   97   98   99   100   101   102   104   105

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM