1. ホーム
  2. r

[解決済み】「'dimnames' [1]の長さが配列の範囲と等しくない」とはどういう意味ですか?

2022-02-07 08:17:50

質問

matplotでプロットできるdata.frameを持っています。

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

しかし、lhの頭を取ってやってみると、変なエラーが出ます。

> 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

ということは、名前に関係することかな?

> 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" 

寸法が同じに見える? 元のフレームでのmatplotは動作しますが、フレームの頭では動作しないので、奇妙なことです。 ここで何が起こっているのでしょうか?

編集、OK、それで、いくつかの質問に答えるために、より小さいので、lhbyzoneの代わりにthbyzoneを使い、データを小さくするためにhead(.,1000)の代わりにheadを使いましょう

> 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, ])

さらに試行錯誤。

> 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

編集する

> 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、ゼロから再現することができます。 reshape (ただし reshape2 ). によって、確かに何かがぐちゃぐちゃになっています。 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

具体的な問題点は utils::head.data.frame は、完全に一貫した内部構造を保ったままオブジェクトの断片をドロップします。 as.matrix.cast_df (によって呼び出される)。 matplot )であり、その構造があることを前提としています。

以下のメソッドを追加すると、問題が解決するようです。

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
}

この件に関しては、メンテナに問い合わせる価値があるかもしれません。 reshape パッケージは非推奨で reshape2 ...

別の回避策としては reshape::cast から reshape2::dcast 出来れば