2

最近、私はこのコードに出くわしました:

y <- NULL

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

ここの2番目の回答から。

y <- list(...)しかし、以下の比較が示すように、 と違いはないようです。

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

ここでブラケットの割り当てで何が起こっていますか? エラーが発生しないのはなぜですか? そして、コードの最後の行にある割り当てなしのバージョンとなぜ違うのでしょうか?

4

1 に答える 1

2

マトリックス インデックスは、yが薄暗い場合にのみ適用されます。Rこれを標準のリサイクルと、すべての行列が実際にはベクトルであるという事実と 組み合わせると、この動作は理にかなっています。

NULL に初期化yすると、dim がないことが保証されます。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)] <- list("A", "B")と、実際には次のようになります。

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

発生するインデックス作成をさらに詳しく見てみましょう: (最初の 2 文字が繰り返されていることに注意してください)

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 を見ると[、次のコメントがあります。

  • 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 */
...
于 2013-08-04T14:47:52.137 に答える