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"
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 ...
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With