74

RI を使用していると、"subscript out of bounds" というエラー メッセージが頻繁に表示されます。:

# 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

ただし、私の質問はこの特定のコードに関するものではありません (それも解決するのに役立ちますが) が、私の質問はより一般的です:

  • 添字範囲外エラーの定義は何ですか? 何が原因ですか?
  • この種のエラーにアプローチする一般的な方法はありますか?
4

7 に答える 7

107

これは、配列の境界外にアクセスしようとするためです。

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

  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. 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])
于 2013-02-22T19:16:08.347 に答える
3

alter > ncol( reach_mat )または または のいずれか、つまり、インデックスが配列の境界を超えていることを意味しますi > nrow( reach_mat )(i が行数よりも大きいか、alter が列数よりも大きい)。

上記のテストを実行して、何がいつ起きているかを確認してください。

于 2013-02-22T19:07:00.867 に答える
2

私は時々同じ問題に遭遇します。私は他の言語ほど R の専門家ではないので、2 番目の箇条書きしかお答えできません。for標準ループには予期しない結果が生じることがわかりました。言うx = 0

for (i in 1:x) {
  print(i)
}

出力は

[1] 1
[1] 0

一方、Pythonの場合、たとえば

for i in range(x):
  print i

何もしません。ループには入りません。

x = 0Rならループに入らないと思っていました。ただし、1:0有効な数値の範囲です。ループifをラップするステートメントを使用する以外に、適切な回避策をまだ見つけていませんfor

于 2013-02-22T19:19:50.843 に答える
1

これは、standfordのsna無料チュートリアルからのものであり、次のように述べています...

# Reachability can only be computed on one vertex at a time. To # get graph-wide statistics, change the value of "vertex" # manually or write a for loop. (Remember that, unlike R objects, # igraph objects are numbered from 0.)

わかりました。igraphを使用する場合、最初のロール/列は1以外は0ですが、行列は1から始まります。したがって、igraphでの計算では、x-1が必要になります。

this_node_reach <- subcomponent(g, (i - 1), mode = m)

しかし、変更の計算については、ここにタイプミスがあります

alter = this_node_reach[j] + 1

+1を削除すると、問題なく動作します

于 2013-03-05T14:23:32.167 に答える