【问题标题】:Strange bracket assignment call ('[<-') with matrix argument带有矩阵参数的奇怪括号赋值调用('[<-')
【发布时间】:2013-08-05 07:47:08
【问题描述】:

最近我偶然发现了这段代码:

y <- NULL

y[cbind(1:2, 1:2)] <- list( list(1,2), list(2,3))

来自第二个答案here

但它似乎与y &lt;- list(...) 没有什么不同,如下面的比较所示:

> identical(y, list( list(1,2), list(2,3)))
[1] TRUE
> identical(y, y[cbind(1:2, 1:2)])
[1] FALSE

这里的括号赋值是怎么回事?为什么它不会抛出错误?还有为什么和最后一行代码中的非赋值版本不一样?

【问题讨论】:

  • 是不是和y[1:2] &lt;- list( list(1,2), list(2,3) )类似。我这里没有看到cbind的功能。
  • @Arun,cbind 的功能被1:2 的重复所掩盖。如果改为使用cbind(1:2, 2:3),那么它会产生效果(尽管与c 没有区别)
  • 里卡多,给我一点时间 :)

标签: r list matrix assignment-operator


【解决方案1】:

矩阵索引仅适用于y 暗淡的情况。 将此与标准R 回收以及所有矩阵实际上都是向量的事实相结合,这种行为是有意义的。

当您将y 初始化为 NULL 时,您确保它没有暗淡。因此,当您通过矩阵索引y 时,例如ind,您会得到与调用y[as.vector(ind)] 相同的结果

identical(y[ind], y[as.vector(ind)])
# [1] TRUE

如果ind 中有重复值并且您也在分配,那么对于每个索引,只有最后分配的值会保留。例如让我们假设我们正在执行

y <- NULL; y[cbind(1:2, 2:1)] <- list( list(1,2), list(3,4) )
#   y has no dimension, so `y[cbind(1:2, 2:1)]` 
#   is the equivalent of   `y[c(1:2, 2:1)]`

当您分配 y[c(1, 2, 2, 1)] &lt;- list("A", "B") 时,实际上发生的情况类似于:

    y[[1]] <- "A"
    y[[2]] <- "B"
    y[[2]] <- "B"  # <~~ 'Overwriting' previous value 
    y[[1]] <- "A"  # <~~ 'Overwriting' previous value 

下面是对发生的索引的进一步了解:(注意前两个字母是如何重复的)

ind <- cbind(1:2, 1:2)
L <- as.list(LETTERS)
L[ind]
# [[1]]
# [1] "A"
# 
# [[2]]
# [1] "B"
# 
# [[3]]
# [1] "A"
# 
# [[4]]
# [1] "B"

这里是同样的事情,现在有分配。 请注意如何只保留分配的第 3 和第 4 个值

L[ind] <- c("FirstWord", "SecondWord", "ThirdWord", "FourthWord")
L[ind]
# [[1]]
# [1] "ThirdWord"
# 
# [[2]]
# [1] "FourthWord"
# 
# [[3]]
# [1] "ThirdWord"
# 
# [[4]]
# [1] "FourthWord"

尝试不同的索引以进一步清晰:

ind <- cbind(c(3, 2), c(1, 3))  ## will be treated as c(3, 2, 1, 3) 
L <- as.list(LETTERS)
L[ind] <- c("FirstWord", "SecondWord", "ThirdWord", "FourthWord")
L[1:5]
#  [[1]]
#  [1] "ThirdWord"
#  
#  [[2]]
#  [1] "SecondWord"
#  
#  [[3]]
#  [1] "FourthWord"
#  
#  [[4]]
#  [1] "D"
#  
#  [[5]]
#  [1] "E"

L[ind]
#  [[1]]
#  [1] "FourthWord"
#  
#  [[2]]
#  [1] "SecondWord"
#  
#  [[3]]
#  [1] "ThirdWord"
#  
#  [[4]]
#  [1] "FourthWord"

编辑@agstudy 的问题:

查看[ 的src,我们有以下cmets:

  • 特殊的 [ 下标 where dim(x) == ncol(subscript matrix)
  • 在 VectorSubset 内处理。下标矩阵转
  • 转换成合适大小的下标向量,然后
  • VectorSubset 继续。

查看函数static SEXP VectorSubset(SEXP x, SEXP s, SEXP call)相关检查如下:

/* lines omitted */ 
attrib = getAttrib(x, R_DimSymbol);
/* lines omitted */
if (isMatrix(s) && isArray(x) && ncols(s) == length(attrib)) {
    /* lines omitted */
...

【讨论】:

  • Ricardo, unlist 对矩阵无效。
  • @Arun,我的意思是as.vector 修复了它。 (感谢指出)
  • 我认为在这里谈论子集有点令人困惑。您的第一个代码部分就在这也许可以使它更清楚。这至少让我感到困惑。也许,最好只坚持作业部分?只是我的想法。
  • Arun,具有讽刺意味的是,这可以更清楚是什么令人困惑,哈哈。让我看看我是否可以给它一个编辑
  • @Arun,我在嘲笑这个讽刺,因为这完全是真的。我重组了我的答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-16
  • 2012-07-15
相关资源
最近更新 更多