0

After getting great help here to randomize a matrix without repetitions in rows and columns (Fixed values not repeated over column and row) I have another question concerning a modification.

So, first start with what has been done: I wanted a matrix with randomized rows and columns without duplications in each (row wise and column) wise. Again thanks to the great help here this is the code by jdobres (https://stackoverflow.com/users/6436545/jdobres) I ended up using:

# number of rows and columns
n <- 10

# create ordered rows and columns
ordered.by.row <- matrix(1:n, n, n)
ordered.by.col <- matrix(1:n, n, n, byrow = T)

# offset the rows and columns relative to each other.
# no row or column has a repeated value, but the values are still ordered
offset <- (ordered.by.row + ordered.by.col) %% n + 1

# shuffle the columns, then shuffle the rows, this produces a randomized matrix
# 'shuffle.row' is the final, randomized matrix
set.seed(1222) # change this to change randomization
shuffle.col <- offset[,sample(1:n, n, replace = F)]
shuffle.row <- shuffle.col[sample(1:n, n, replace = F), ]

# verify solution
any(apply(shuffle.row, 1, function(r)any(duplicated(r)))) # FALSE
any(apply(shuffle.row, 2, function(r)any(duplicated(r)))) # FALSE


> # create ordered rows and columns
ordered.by.row <- matrix(1:n, n, n)
ordered.by.col <- matrix(1:n, n, n, byrow = T)

# offset the rows and columns relative to each other.
# no row or column has a repeated value, but the values are still ordered
offset <- (ordered.by.row + ordered.by.col) %% n + 1

# shuffle the columns, then shuffle the rows, this produces a randomized matrix
# 'shuffle.row' is the final, randomized matrix
set.seed(1222) # change this to change randomization
shuffle.col <- offset[,sample(1:n, n, replace = F)]
shuffle.row <- shuffle.col[sample(1:n, n, replace = F), ]

# verify solution
any(apply(shuffle.row, 1, function(r)any(duplicated(r)))) # FALSE
any(apply(shuffle.row, 2, function(r)any(duplicated(r)))) # FALSE

      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]    1   10    6    9    2    8    3    5    7     4
 [2,]    3    2    8    1    4   10    5    7    9     6
 [3,]    7    6    2    5    8    4    9    1    3    10
 [4,]    9    8    4    7   10    6    1    3    5     2
 [5,]   10    9    5    8    1    7    2    4    6     3
 [6,]    2    1    7   10    3    9    4    6    8     5
 [7,]    8    7    3    6    9    5   10    2    4     1
 [8,]    6    5    1    4    7    3    8   10    2     9
 [9,]    5    4   10    3    6    2    7    9    1     8
[10,]    4    3    9    2    5    1    6    8   10     7

However I have the issue now that I want my first rows (lets say row 1,2,3) fixed in a specific order. Nevertheless I need new rows 4 to 10 to again be randomized and without duplicates (also no duplicates concerning rows 1-3)!

So for example I have 3 rows like this:

      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]    8    7    3    6    9    5   10    2    4     1
 [2,]    6    5    1    4    7    3    8   10    2     9
 [3,]    5    4   10    3    6    2    7    9    1     8

BUT for the next 7 rows I want randomized but not duplicated (in any row or column) values without changing the first rows...

Any ideas? I cannot figure out how to exclude the ones I want to stay (row 1-3) from shuffeling but still have no duplicates in the rest of the rows and columns...

Your help would be again much appreciated!

EDIT:

Thank you very much Moody_Mudskipper for you help! This what the solution looks like using my (fake) data:

mat<-as.matrix(first.rows)
nkeep <- 3
mat_shuffled <- mat[c(1:nkeep,sample((nkeep+1):nrow(mat),replace=FALSE)),]

    [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
row1    1    4    7    6    5    3    2    8    9    10
row2   10    7    3    2    1    4    5    9    8     6
row3    9    2    4    3    5    7   10    1    6     5
       10    7    9    6    8    2    5    4    3     1
        1   10    8    4    7    3    5    2    6     9
       10    6    4    1    8    3    7    2    5     9
        2    5    7    8    9    6    1    3    4    10
        2    1   10    4    8    9    3    6    5     7
        8    5    3    2    4    1   10    7    6     9
        6    1    5    4    2   10    3    8    7     9

THANKY YOU!!

SEE Constructing a randomised matrix with no duplicates but fixed partial input FOR A SOLUTION BY FERNANDO THAT ALSO KEEPS THE VALUES IN COLUMNS UNIQUE

shampoo
  • 57
  • 6
  • You could specify the row indices to prevent the function from shuffling rows 1-3, e.g. `matrix[4:nrow(matrix),]` – sempervent Sep 12 '17 at 11:50
  • Thank you! But where would I implement this specification? As I already need the rows fixed before the offset ... Please, see edit above for a better description of the problem – shampoo Sep 12 '17 at 21:47

1 Answers1

0

Would this work ?

mat <- matrix(1:100,10)
nkeep <- 3
mat_shuffled <- mat[c(1:nkeep,sample((nkeep+1):nrow(mat),replace=FALSE)),]
#      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,]    1   11   21   31   41   51   61   71   81    91
# [2,]    2   12   22   32   42   52   62   72   82    92
# [3,]    3   13   23   33   43   53   63   73   83    93
# [4,]    6   16   26   36   46   56   66   76   86    96
# [5,]   10   20   30   40   50   60   70   80   90   100
# [6,]    7   17   27   37   47   57   67   77   87    97
# [7,]    4   14   24   34   44   54   64   74   84    94
# [8,]    5   15   25   35   45   55   65   75   85    95
# [9,]    9   19   29   39   49   59   69   79   89    99
# [10,]   8   18   28   38   48   58   68   78   88    98
moodymudskipper
  • 46,417
  • 11
  • 121
  • 167
  • Thanks! I tried this but I get an error of "subcript out of bound"....Please, see edit above for a better description of the problem! – shampoo Sep 12 '17 at 21:48
  • There were 3 mistakes sorry :). it's fixed now! – moodymudskipper Sep 12 '17 at 21:54
  • GREAT!! Thank you very much!! This works nicely now! Do you maybe also know how to solve my issue with the duplicated values in columns (see problem 1 in the edit of the original question)?? I do understand why it is returning my duplicates in the first place (because I use rbind) however I don´t know how to avoid that issue ... – shampoo Sep 12 '17 at 22:30
  • so any row that contains a value already present upwards in same column should be disqualified? at this point it's really better tostart a new question, and do it 100% from a simple fake reproducible example, and give the exact output you want (use seed if you use sample) – moodymudskipper Sep 12 '17 at 22:40
  • https://stackoverflow.com/questions/46186549/constructing-a-randomised-matrix-with-no-duplicates-but-fixed-partial-input – shampoo Sep 12 '17 at 23:09