“dimnames”的长度[1]不等于数组范围的含义是什么?

20

我有一个数据框,可以使用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,因为它更小,而且让我们使用head而不是head(..,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

编辑:

> 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
这里有些不对劲。如果真的是head(lhybyzone),那么dim(foo)不应该显示1000行。默认情况下,head只返回6行。这不是我们要找的foo。我们喜欢一致性,否则我们会认为“嘿嘿,你没有做你认为你在做的事情”。 - Spacedman
你说得对,我之前使用了 head(.., 1000)。已经更新了。 - Hugh Perkins
options(error = recover)也可以帮助您... - aL3xa
1
我们需要更多了解您的lhbyzone对象。它是矩阵还是数据框?如果您使用[1:1000,]而不是使用head,会发生什么?class(lhbyzone)是什么?str(lhbyzone)是什么?等等。 - Spacedman
@Spacedman,它不能是一个矩阵(因为names(foo)不是NULL),但除此之外这些都是好问题。@HughPerkins,如果你尝试as.matrix(foo)会发生什么? - Ben Bolker
显示剩余2条评论
7个回答

13

好的,我可以从头开始使用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.frameas.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::cast切换到reshape2::dcast...

尽管我认为reshape包已被弃用,推荐使用reshape2,但联系维护者可能是值得的...


好的,干得漂亮!不过我不确定如何在reshape2中使用melt(https://dev59.com/RWnWa4cB1Zd3GeqP4trK)。我想我可以卸载reshape2来使用melt,然后重新加载它以使用dcast? - Hugh Perkins
哦,我可以使用 reshape::melt 使用 reshape 中的 melt 函数,直接使用 dcast 使用 reshape2 中的 dcast 函数。太棒了,我会将这个答案标记为已接受。谢谢 Ben! - Hugh Perkins
4
不是因为“头部问题”,因为 matplot(z[1:6,]) 也出现了类似的错误……matplot 的线条变粗了。 - Spacedman
cast正在创建一个cast_df类的对象,我猜它的子集方法在某个地方出了问题... - Spacedman

9
我遇到了同样的错误。虽然这个答案不适用于这个问题的具体示例,但它可能会帮助未来前来此页面寻求错误解决方案的用户。
我的列名包含数字和符号,例如17:901。这导致了错误。使用make.names函数将我的列名转换为“语法上有效的名称”,例如names(df)<-make.names(names(df)) 这解决了问题。

这对我没有起作用。可能我有不同的错误来源。我发布了我的问题:https://stackoverflow.com/questions/66139742/column-names-listed-but-names-shows-null-error-in-dimnamesx-dn-length - Sander Heinsalu

3

我曾经遇到过同样的错误,但在我的情况下,一个列(最后一个)在合并后只有NA值。删除这一列可以恢复正常。您可以检查确认是否存在类似的问题。


我有同样的错误,但是原因不同,因为没有NA列。似乎R中有许多bug会生成这个错误消息。 - Sander Heinsalu

2
对于那些在使用 mvoutlier::plot.mvoutlierCoDa(...) 时收到此错误的人,这个错误是由于参数 onlyout(仅绘制异常值)设置为TRUE(默认),而你的数据集不包含任何异常值所导致的。将 onlyout=FALSE 应该可以解决问题。运行 mvoutlier.CoDa(df)$outliers 来查看你的数据集是否包含异常值。"最初的回答"

1

我遇到了类似的问题,尝试将 data.frame 转换为 data.table 时也出现了相同的问题。我通过以下方式解决:

data <- data %>% as.matrix(.) %>% as.data.table(.)

0

可能有帮助的信息

我遇到了一个类似的问题,涉及到名称为股票代码的xts对象。
对象y和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", ) :

'dimnames'的长度[1]与数组范围不相等

但是

names(z) <- make.names(names(z))

dim(z["2019-08",])

[1] 31 10

不知道为什么xts[]选择在对象y上可以工作,但在z上却不行。

现在我只需要编写一个快速的辅助函数,从新的“语法上有效”(但不再是语义上有效的)名称中获取股票代码即可。


这两个对象的class()和str()输出是什么?它们的类是否相同? - San Emmanuel James

0

我收到了错误信息,因为我使用了自定义列名,但不小心忘记了一个列。建议尝试在不选择列名的情况下运行它,以确保没有遗漏任何列。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接