1

I'm new to R and would like to know how I can set row names to a large matrix with dimensions 92,235 x 17.

I want to set the row names so that it goes from "1 x 2", "1 x 3", "1 x 4" ... "1 x 430", "2 x 3", "2 x 4" ... "2 x 430", "3 x 4", "3 x 5" ... "3 x 430" ... "429 x 430".

I know I'll need two for-loops

for(i in 1:430) {
    for(j in seq(from = i+1, to = 430, by = 1))
        # set row names
}

But once I do this I get the error

Error in seq.default(from = i + 1, to = 430, by = 1) : wrong sign in 'by' argument

How do I correct this error and how do I go about customising my row names?

TIA

pophahpop
  • 51
  • 5
  • 1
    It's nice to have an example we can work with, like the `mat <- matrix(1:4)` in dayne's answer. Here are some general suggestions on asking: http://stackoverflow.com/q/5963269/1191259 – Frank May 08 '15 at 15:22
  • The error is happening because when `i=430` it starts counting `j` at `from=i+1=431` which is greater than `to=430`. I think you mean for `i` to go only `1:429` – Frank May 08 '15 at 15:29

2 Answers2

3

You do not need a loop here. You can set the row names for a matrix using the rownames function as follows.

mat <- matrix(1:4)
rownames(mat)
# NULL

rownames(mat) <- c("row1", "row2", "row3", "row4")

mat
#      [,1]
# [1,]    1
# [2,]    2
# [3,]    3
# [4,]    4

rownames(mat) <- c("row1", "row2", "row3", "row4")
mat
#      [,1]
# row1    1
# row2    2
# row3    3
# row4    4

You can create your custom row names using a combination of rep and paste:

paste(rep(1:2, each = 5), "x", 1:5)
# [1] "1 x 1" "1 x 2" "1 x 3" "1 x 4" "1 x 5" 
# [2] "2 x 1" "2 x 2" "2 x 3" "2 x 4" "2 x 5"

... or for your specific example:

paste(rep(1:215, each = 430), "x", 1:430)[1:92235]

In general you can use the formula:

paste(rep(1:ceiling(nrow(mat)/n), each = n), "x", 1:n)[1:nrow(mat)]

where n is the number of times you want the first number repeated.

EDIT BASED ON COMMENT

To get row names that do not include "2 x 1", one approach would be to use expand.grid:

library(data.table)
tmp <- as.data.table(expand.grid(1:2, 1:5))
tmp <- tmp[Var2 > Var1][order(Var1)]
paste(tmp$Var1, "x", tmp$Var2)
# [1] "1 x 2" "1 x 3" "1 x 4" "1 x 5" 
# [2] "2 x 3" "2 x 4" "2 x 5"
dayne
  • 7,504
  • 6
  • 38
  • 56
1

The reason for the error message is simply that for i=430, the second loop tries to run from 431 to 430 with increment +1. R realizes that the increment should be negative and thus throws an error.

Now for your specific problem: as dayne already pointed out, you can use rownames to set the row names of your matrix. The names you should rather generate using apply functions than for loops. This is a possibility.

M <- matrix(rep(0,92235*17),ncol=17)
rn <- unlist(sapply(1:429,function(i) paste(i,"x",(i+1):430)))
rownames(M) <- rn

But there is probably a more elegant way to achieve this...

Stibu
  • 15,166
  • 6
  • 57
  • 71
  • Thanks for clarifying the error message! It's a kind of off-by-one-error isn't it? – pophahpop May 09 '15 at 10:52
  • Conceptually, you mad an off-by-one-error, because you let your first for-loop run to 430, even though you actually only need it to go to 429. But the error message has another origin: R realises that you started an infinite loop (from 431 to 430 with increment +1) and thus it stops. – Stibu May 09 '15 at 11:29