Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does 'length of 'dimnames' [1] not equal to array extent' mean?

Tags:

r

I have a data.frame, which I can plot using matplot:

> dim(lhbyzone)
[1] 38070    21
> matplot(lhbyzone)
(no error occurs here)

But if I take the head of lh, and try, it gives me a strange error:

> foo <- head(lhbyzone,1000)
> matplot(foo)
Error in `rownames<-`(`*tmp*`, value = c("1", "2", "3", "4", "5", "6",  : 
  length of 'dimnames' [1] not equal to array extent

So, maybe something to do with the names?

> dimnames(foo)
[[1]]
   [1] "1"    "2"    "3"    "4"    "5"    "6"    "7"    "8"    "9"    "10"  
  [11] "11"   "12"   "13"   "14"   "15"   "16"   "17"   "18"   "19"   "20"  
  [21] "21"   "22"   "23"   "24"   "25"   "26"   "27"   "28"   "29"   "30"  
  [31] "31"   "32"   "33"   "34"   "35"   "36"   "37"   "38"   "39"   "40"  
...
 [951] "951"  "952"  "953"  "954"  "955"  "956"  "957"  "958"  "959"  "960" 
 [961] "961"  "962"  "963"  "964"  "965"  "966"  "967"  "968"  "969"  "970" 
 [971] "971"  "972"  "973"  "974"  "975"  "976"  "977"  "978"  "979"  "980" 
 [981] "981"  "982"  "983"  "984"  "985"  "986"  "987"  "988"  "989"  "990" 
 [991] "991"  "992"  "993"  "994"  "995"  "996"  "997"  "998"  "999"  "1000"

[[2]]
 [1] "time" "z1"   "z2"   "z3"   "z4"   "z5"   "z6"   "z7"   "z8"   "z9"  
[11] "z10"  "z11"  "z12"  "z13"  "z14"  "z15"  "z16"  "z17"  "z18"  "z19" 
[21] "z20" 

> dim(foo)
[1] 1000   21

> names(foo)
 [1] "time" "1"    "2"    "3"    "4"    "5"    "6"    "7"    "8"    "9"   
[11] "10"   "11"   "12"   "13"   "14"   "15"   "16"   "17"   "18"   "19"  
[21] "20" 

The dimensions look the same? It's odd, since matplot on the original frame works, but not on the head of the frame. What could be happening here?

Edit, ok, so to answer some questions, and let's use thbyzone instead of lhbyzone, because it's smaller, and let's use head instead of head(..,1000) to make the data smaller

> head(thbyzone)
  time  1  2  3  4  5  6  7  8  9 10 11
1    1 46 38 44 45 42 44 45 43 41 42 36
2    2 46 36 42 43 42 43 44 44 39 43 32
3    3 45 35 40 41 40 42 41 42 36 43 31
4    4 41 30 36 37 39 38 40 34 35 39 30
5    5 39 30 34 33 40 38 35 30 33 35 34
6    6 35 29 32 32 41 37 35 35 36 35 35

> dimnames(head(thbyzone))
[[1]]
[1] "1" "2" "3" "4" "5" "6"

[[2]]
 [1] "time" "1"    "2"    "3"    "4"    "5"    "6"    "7"    "8"    "9"   
[11] "10"   "11" 

> matplot(head(thbyzone))
Error in `rownames<-`(`*tmp*`, value = c("1", "2", "3", "4", "5", "6",  : 
  length of 'dimnames' [1] not equal to array extent

> matplot(as.matrix(head(thbyzone)))
Error in `rownames<-`(`*tmp*`, value = c("1", "2", "3", "4", "5", "6",  : 
  length of 'dimnames' [1] not equal to array extent

> matplot(thbyzone[1:6,])
Error in `rownames<-`(`*tmp*`, value = c("1", "2", "3", "4", "5", "6",  : 
  length of 'dimnames' [1] not equal to array extent

> class(thbyzone)
[1] "cast_df"    "data.frame"

> str(thbyzone)
List of 12
 $ time: num [1:39432] 1 2 3 4 5 6 7 8 9 10 ...
 $ 1   : int [1:39432] 46 46 45 41 39 35 33 33 36 47 ...
 $ 2   : int [1:39432] 38 36 35 30 30 29 28 28 28 33 ...
 $ 3   : int [1:39432] 44 42 40 36 34 32 30 30 30 32 ...
 $ 4   : int [1:39432] 45 43 41 37 33 32 30 29 30 41 ...
 $ 5   : int [1:39432] 42 42 40 39 40 41 38 33 36 43 ...
 $ 6   : int [1:39432] 44 43 42 38 38 37 36 36 38 44 ...
 $ 7   : int [1:39432] 45 44 41 40 35 35 33 30 31 39 ...
 $ 8   : int [1:39432] 43 44 42 34 30 35 34 33 34 41 ...
 $ 9   : int [1:39432] 41 39 36 35 33 36 32 31 31 35 ...
 $ 10  : int [1:39432] 42 43 43 39 35 35 33 33 35 42 ...
 $ 11  : int [1:39432] 36 32 31 30 34 35 32 30 28 30 ...
 - attr(*, "row.names")= int [1:39432] 1 2 3 4 5 6 7 8 9 10 ...
 - attr(*, "idvars")= chr "time"
 - attr(*, "rdimnames")=List of 2
  ..$ :'data.frame':    39432 obs. of  1 variable:
  .. ..$ time: num [1:39432] 1 2 3 4 5 6 7 8 9 10 ...
  ..$ :'data.frame':    11 obs. of  1 variable:
  .. ..$ station_id: int [1:11] 1 2 3 4 5 6 7 8 9 10 ...

> traceback()
.... lots of lines ...
   "39405", "39406", "39407", "39408", "39409", "39410", "39411", 
   "39412", "39413", "39414", "39415", "39416", "39417", "39418", 
   "39419", "39420", "39421", "39422", "39423", "39424", "39425", 
   "39426", "39427", "39428", "39429", "39430", "39431", "39432"
   ))
4: as.matrix.cast_df(y)
3: as.matrix(y)
2: ncol(y <- as.matrix(y))
1: matplot(thbyzone[1:6, ])

Some more attempts:

> foo <- head(thbyzone)
> foo$time <- NULL
> matplot(foo)
Error in `rownames<-`(`*tmp*`, value = c("1", "2", "3", "4", "5", "6",  : 
  length of 'dimnames' [1] not equal to array extent
> head(foo)
   1  2  3  4  5  6  7  8  9 10 11
1 46 38 44 45 42 44 45 43 41 42 36
2 46 36 42 43 42 43 44 44 39 43 32
3 45 35 40 41 40 42 41 42 36 43 31
4 41 30 36 37 39 38 40 34 35 39 30
5 39 30 34 33 40 38 35 30 33 35 34
6 35 29 32 32 41 37 35 35 36 35 35

Edit:

> options(error=recover)
> matplot(thbyzone[1:6,])
Error in `rownames<-`(`*tmp*`, value = c("1", "2", "3", "4", "5", "6",  : 
  length of 'dimnames' [1] not equal to array extent

Enter a frame number, or 0 to exit   

1: matplot(thbyzone[1:6, ])
2: ncol(y <- as.matrix(y))
3: as.matrix(y)
4: as.matrix.cast_df(y)
5: `rownames<-`(`*tmp*`, value = c("1", "2", "3", "4", "5", "6", "7", "8", "9"
like image 315
Hugh Perkins Avatar asked Oct 20 '12 05:10

Hugh Perkins


2 Answers

OK, I can reproduce this from scratch, with reshape (but not with reshape2). Something is indeed getting mangled by head().

d <- data.frame(time=rep(1:10,10),x=rep(1:10,each=10),y=1:100)
library(reshape2)
str(dcast(d,time~x))  ## regular data frame
detach("package:reshape2")
library(reshape)
str(z <- cast(d,time~x))
matplot(head(z))  ## error

The specific problem is an interaction between utils::head.data.frame, which drops pieces of the object without keeping a completely consistent internal structure, and as.matrix.cast_df (called by matplot), which assumes that structure is there.

Adding the following method seems to fix the problem.

head.cast_df <- function (x, n = 6L, ...)  {
    stopifnot(length(n) == 1L)
    n <- if (n < 0L) {
        max(nrow(x) + n, 0L)
    } else min(n, nrow(x))
    h <- x[seq_len(n), , drop = FALSE]
    ## fix cast_df-specific row names element
    attr(h,"rdimnames")[[1]] <- rdimnames(h)[[1]][seq_len(n),,drop=FALSE]
    h
}

It might be worth contacting the maintainer about this, although the reshape package is (I think) deprecated in favor of reshape2 ...

An alternative workaround is to switch from reshape::cast to reshape2::dcast if possible ...

like image 161
Ben Bolker Avatar answered Nov 16 '22 22:11

Ben Bolker


I had the same error. Although this answer does not apply to the specific example of this question, it may help future users who travel to this page for help with the error.

The names of my columns contained numbers and symbols such as 17:901. This was throwing the error. Using the make.names function turned my column names into 'syntactically valid names' eg. names(df)<-make.names(names(df))

This solved the problem.

like image 9
J.Con Avatar answered Nov 17 '22 00:11

J.Con