2
votes

I want a 7*17 matrix.
row names are from 2:8 ( first row name to be 2, 2nd row to be 3 and ...)
colnames are 4:17 ( first column has name 4 and 2nd column has name 5 and ... )
matrix elements are filled such that mat[i,j] = rowname of ith row * colnames of jth col.

I get error with what I m attempting:

mat <- matrix(0, nrow = 7, ncol = 17 , byrow = TRUE)
for (rr in 2:8) {
  row.names(mat)[rr-1] <- paste('class', rr, sep='.')
  for(cc in 4:20){
    mat[rr-1,cc-3] <- rr*cc
    colnames(mat)[cc] <- paste('count', cc, sep='.')
      }
}

this is the error:

Error in dimnames(x) <- dn : length of 'dimnames' [1] not equal to array

how can I fix this.

1
Ought to be used a matrix or could you use a dataframe with one column containing names?SNR

1 Answers

2
votes

There are several problems with the code in the question:

  1. It is trying to insert names into the names vectors but no names have been set on the matrix.
  2. colnames(mat)[cc]<-... should be colnames(mat)[cc-3]<-
  3. Using byrow=TRUE is not an error but it is pointless since every element is 0 so it doesn't matter what order 0 is inserted.

1) Suggest doing it this way instead:

rr <- 2:8
cc <- 4:20
mat <- outer(rr, cc)
dimnames(mat) <- list(paste0("class.", rr), paste0("count.", cc))

2) Alternately, this could be done via list comprehensions using the listcompr package. For each value of r in rr the gen.named.vector call creates a named vector forming one row and then gen.named.matrix creates a matrix from the rows.

library(listcompr)
gen.named.matrix("class.{r}", gen.named.vector("count.{c}", c*r, c = cc), r = rr)

3) If you want to fix up the code in the question then do it like this:

mat <- matrix(0, nrow = 7, ncol = 17 ,
  dimnames = list(character(7), character(17)))
for (rr in 2:8) {
  rownames(mat)[rr-1] <- paste('class', rr, sep='.')
  for(cc in 4:20) {
    mat[rr-1, cc-3] <- rr * cc
    colnames(mat)[cc-3] <- paste('count', cc, sep='.')
  }
}