1. ホーム
  2. スクリプト・コラム
  3. その他

[解決済み] 境界外の添え字 - 一般的な定義と解決策?

2022-01-12 05:26:24

質問

Rのコードは以下の通りです。

# Load necessary libraries and data
library(igraph)
library(NetData)
data(kracknets, package = "NetData")

# Reduce dataset to nonzero edges
krack_full_nonzero_edges <- subset(krack_full_data_frame, (advice_tie > 0 | friendship_tie > 0 | reports_to_tie > 0))

# convert to graph data farme 
krack_full <- graph.data.frame(krack_full_nonzero_edges) 

# Set vertex attributes
for (i in V(krack_full)) {
    for (j in names(attributes)) {
        krack_full <- set.vertex.attribute(krack_full, j, index=i, attributes[i+1,j])
    }
}

# Calculate reachability for each vertix
reachability <- function(g, m) {
    reach_mat = matrix(nrow = vcount(g), 
                       ncol = vcount(g))
    for (i in 1:vcount(g)) {
        reach_mat[i,] = 0
        this_node_reach <- subcomponent(g, (i - 1), mode = m)

        for (j in 1:(length(this_node_reach))) {
            alter = this_node_reach[j] + 1
            reach_mat[i, alter] = 1
        }
    }
    return(reach_mat)
}

reach_full_in <- reachability(krack_full, 'in')
reach_full_in

実行すると、エラーが発生します。

Error in reach_mat[i, alter] = 1 : subscript out of bounds .

しかし、私の質問はこの特定のコードの部分についてではなく、(それも解決してくれると助かるのですが)私の質問はもっと一般的なものです。

  • subscript-out-of-bounds エラーの定義は何ですか?また、その原因は何ですか?
  • この種のエラーに対処する一般的な方法はありますか?

解決方法は?

これは、配列の境界を越えてアクセスしようとしたためです。

このようなエラーをデバッグする方法を紹介します。

  1. を設定しました。 options(error=recover)
  2. 私が実行する reach_full_in <- reachability(krack_full, 'in') 私は得る。

    reach_full_in <- reachability(krack_full, 'in')
    Error in reach_mat[i, alter] = 1 : subscript out of bounds
    Enter a frame number, or 0 to exit   
    1: reachability(krack_full, "in")
    
    
  3. 1を入力すると

     Called from: top level 
    
    
  4. I タイプ ls() をクリックすると、現在の変数が表示されます。

      1] "*tmp*"           "alter"           "g"               
         "i"               "j"                     "m"              
        "reach_mat"       "this_node_reach"
    
    

次に、変数の寸法を確認します。

Browse[1]> i
[1] 1
Browse[1]> j
[1] 21
Browse[1]> alter
[1] 22
Browse[1]> dim(reach_mat)
[1] 21 21

alterが圏外になっているのがわかりますね。22 > 21 .ライン内:

  reach_mat[i, alter] = 1

このようなエラーを回避するために、個人的には次のようにしています。

  • を使ってみてください。 applyxx 関数を使用します。よりも安全です。 for
  • を使っています。 seq_along でなく 1:n (1:0)
  • を避けるために、できる限りベクトル化した解法で考えるようにしましょう。 mat[i,j] インデックスアクセス

解答をEDITベクトル化する

例えば、ここでは、以下の事実を使用していないことがわかります。 set.vertex.attribute はベクトル化されています。

置き換えることができます。

# Set vertex attributes
for (i in V(krack_full)) {
    for (j in names(attributes)) {
        krack_full <- set.vertex.attribute(krack_full, j, index=i, attributes[i+1,j])
    }
}

をこれによって

##  set.vertex.attribute is vectorized!
##  no need to loop over vertex!
for (attr in names(attributes))
      krack_full <<- set.vertex.attribute(krack_full, 
                                             attr, value = attributes[,attr])