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 extentSo, 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 35Edit:
> 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" 7 7 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)) ## errorThe 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.
1I had the same error, but in my case one column (the last) had only NA values after agglomeration. Dropping this column restored sanity. You may check to confirm that you don't have a similar issue going on.
1For those who received this error when using mvoutlier::plot.mvoutlierCoDa(...), this error is produced when the argument onlyout (only plot outliers) is set to TRUE (default) and your dataset does not contain any outliers. Setting onlyout=FALSE should work. Run mvoutlier.CoDa(df)$outliers to see if your dataset contains outliers.
I had a similar problem using a data.frame that I tried to convert to a data.table and gave me the same problem. I solved by:
data <- data %>% as.matrix(.) %>% as.data.table(.) Possibly helpful FYI
I had a similar issue with xts objects with names that are ticker symbols.
objects y and z
names(z)
[1] "000100 KS" "000333 C2" "000423 CH" "000651 CH" "000660 KS" "002008 C2" "002415 C2" "002456 C2" [9] "002475 CH"
"002747 CH"
all.equal(names(y),names(z)) TRUE
all.equal(index(y),index(z)) TRUE
dim(y) 489 10
dim(z) 489 10
dim(y["2019-08",])
[1] 31 10
dim(z["2019-08",])
Error in [.xts(z, "2019-08", ) :
length of 'dimnames' [1] not equal to array extent
but
names(z) <- make.names(names(z))
dim(z["2019-08",])
[1] 31 10
No idea why xts[] selection works on object y but not z.
Now I just have to write a quick helper function to get the tickers back from the new "syntactically valid" (but no longer semantically valid...) names.
1I received the error because I was using custom column names but had accidentally forgotten one column. It could be worth trying to run it without choosing the column names to make sure you aren't missing any.