使用NULL对数组进行子集操作不会删除维度?

4

我想知道是否有任何原因导致这种默认行为?如果有一些关于它的一致性怪癖,我很乐意知道。

以下是两个不同的查询(结果分别为20和0),但我希望它们在删除冗余维度方面具有相同的行为。出于某种原因,使用NULL进行子集操作似乎会保留空维度。 ?drop指令如下:

删除只有一个级别的数组的维度。

使用drop=TRUE时为什么要保留0级维度呢?

我正在开发类似数组的类,由于这个问题,我遇到了与base::array的不一致之处。我应该向R dev平台报告这样的问题吗?

set.seed(1L)
ar.dimnames = list(color = sort(c("green","yellow","red")), 
                   year = as.character(2011:2015), 
                   status = sort(c("active","inactive","archived","removed")))
ar.dim = sapply(ar.dimnames, length)
ar = array(sample(c(rep(NA, 4), 4:7/2), prod(ar.dim), TRUE), 
           unname(ar.dim),
           ar.dimnames)
r1 = ar["green",,,drop=TRUE]
dimnames(r1)
#$year
#[1] "2011" "2012" "2013" "2014" "2015"
#
#$status
#[1] "active"   "archived" "inactive" "removed" 
#
length(r1)
#[1] 20
r2 = ar[NULL,,,drop=TRUE]
dimnames(r2)
#$color
#NULL
#
#$year
#[1] "2011" "2012" "2013" "2014" "2015"
#
#$status
#[1] "active"   "archived" "inactive" "removed" 
#
length(r2)
#[1] 0

1
不清楚您希望输出的样子是什么。它应该具有0 5 4的维度还是只有5 4?在前一种情况下,维度名称应该保留。我可能会选择ar[NA_integer_,,]而不是NULL0L - Frank
1
相关C代码:https://github.com/wch/r-source/blob/de36cb25a08cd14db5569b85cc6335d39caa0cf6/src/main/array.c#L306 - Frank
是的,长度为0的维度也可以被删除,导致c(5,4),当前的dimnames将保持不变,没有第一个元素。 - jangorecki
1
@Roland 我想这已经有文档记录了:?drop 中写道:“删除仅包含一个级别的数组的维度。” 没有提及如何处理零个级别。 - Frank
1
@Frank,好眼力。我本来期望结果长度为0,所以它基本上不能有c(5,4)维度,否则当prod(c(5,4))时就不会评估为0。因此,0维度是正确的,因为prod(c(0,5,4))将评估为0长度。@user7669的答案在这里也非常准确。 - jangorecki
显示剩余5条评论
1个回答

3
实际上,如果您在示例中使用drop=FALSE,您将看到在第一种情况下,第一维具有1个级别,而在第二种情况下它没有级别。因此,drop的行为并不完全一致。抱歉,我看到您已经意识到了这一点。但是,这样做的后果是r2是一个没有条目的数组。由于条目数必须等于维度的乘积,像您想要的那样删除第一维会产生错误。换句话说:当您只有一个级别时可以删除,因为1*5*4=5*4,而不能删除0级别,因为0*5*4=0,这与5*4不同。
具体回答您的问题:
1. 是的,这种默认行为背后存在原因。您不能删除具有0级别的维度,因为如果剩余的维度具有多个级别,则在删除后,条目数量(0)将不再与维度的乘积相匹配。
2. 保留0级别维度的重点在于,用NULL子集化数组的结果是一个没有条目的数组。这与数组的切片(1级)不同,后者仍具有条目,并且不能视为少一维的数组。因此,在0级别上进行删除没有意义(可能唯一可能的行为是如果有一个级别为0,则全部删除维度,但您将失去dimnames等信息)。
3. 不,您不应该向R dev平台报告此问题。

谢谢。我已经添加了一些细节到答案中。希望现在它更像一个合适的答案。 - user7669
1
@Milap 谢谢。我已经具体回答了这些问题。希望现在它更像一个合适的答案。 - user7669
没错 - 那就是一个答案!感谢您接受建设性的意见并采取行动。祝你好运! - Mogsdad

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