Что означает "длина" dimnames "[1], не равная размеру массива?

У меня есть data.frame, который я могу построить с использованием matplot:

> 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 на исходной раме работает, но не на голове рамки. Что может быть здесь?

Редактируйте, хорошо, чтобы ответить на некоторые вопросы, и позвольте использовать thbyzone вместо lhbyzone, потому что он меньше и позволяет использовать голову вместо головы (.., 1000), чтобы уменьшить данные

> 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

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"

Ответ 1

ОК, я могу воспроизвести это с нуля, 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, если это возможно...

Ответ 2

У меня была такая же ошибка. Хотя этот ответ не относится к конкретному примеру этого вопроса, он может помочь будущим пользователям, которые перейдут на эту страницу за помощью в устранении ошибки.

Имена моих столбцов содержали цифры и символы, такие как 17:901. Это выбрасывало ошибку. Использование функции make.names превратило мои имена столбцов в "синтаксически допустимые имена", например. names(df)<-make.names(namesdf))

Это решило проблему.

Ответ 3

У меня была та же ошибка, но в моем случае один столбец (последний) имел только значения NA после агломерации. Сброс этой колонны восстановил здравомыслие. Вы можете проверить, чтобы подтвердить, что у вас нет подобных проблем.

Ответ 4

Для тех, кто получил эту ошибку при использовании mvoutlier::plot.mvoutlierCoDa(...), эта ошибка возникает, когда для аргумента onlyout (только выбросы графика) задано значение TRUE (по умолчанию), а ваш набор данных не содержит никаких выбросов. Установка onlyout=FALSE должна работать. Запустите mvoutlier.CoDa(df)$outliers чтобы увидеть, содержит ли ваш набор данных выбросы.