使用NULL子集数组不会丢弃维度?

时间:2016-03-26 23:41:47

标签: arrays r multidimensional-array

我想知道这种默认行为背后是否有任何原因?如果有一些关于这一点的一致性怪癖,我会很高兴知道。

下面两个不同的查询(产生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 :(得分:3)

事实上,如果你在你的例子中使用drop = FALSE,你会发现在第一种情况下第一个维度有1个级别,而在第二个维度中它有0个级别。所以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平台。