Rを使用しているときに、「subscript out of bound」というエラーメッセージが頻繁に表示されます。 例 :
# 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
が生成されます。
しかし、私の質問はこの特定のコードに関するものではありません(それを解決することも役立ちますが)が、私の質問はより一般的です:
これは、境界外の配列にアクセスしようとするためです。
このようなエラーをデバッグする方法を示します。
options(error=recover)
を設定しました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")
1を入力すると、
Called from: top level
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]
インデックスアクセスを回避できる場合は、ベクトル化されたソリューションで考えてみてください。解をベクトル化する編集
たとえば、ここでは、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])
これが誰かを助けるなら、私が書いた関数でpurr :: map()を使用しているときにこれに遭遇しました。
find_nearby_shops <- function(base_account) {
states_table %>%
filter(state == base_account$state) %>%
left_join(target_locations, by = c('border_states' = 'state')) %>%
mutate(x_latitude = base_account$latitude,
x_longitude = base_account$longitude) %>%
mutate(dist_miles = geosphere::distHaversine(p1 = cbind(longitude, latitude),
p2 = cbind(x_longitude, x_latitude))/1609.344)
}
nearby_shop_numbers <- base_locations %>%
split(f = base_locations$id) %>%
purrr::map_df(find_nearby_shops)
サンプルでこのエラーが発生することもありますが、ほとんどの場合は発生しません。問題の根本は、base_locationsテーブル(PR)の状態の一部がstates_tableに存在しなかったため、本質的にすべてをフィルター処理し、空のテーブルを渡して変換していました。 ストーリーの教訓は、コードの問題ではなく、データの問題があるかもしれないということです(したがって、データをクリーンアップする必要があるかもしれません。)
デバッグを支援してくれたagstudyとzx8754の上記の回答に感謝します。
つまり、alter > ncol( reach_mat )
またはi > nrow( reach_mat )
のいずれか、つまり、インデックスが配列の境界を超えていることを意味します(iは行数よりも大きいか、alterは列数よりも大きい)。
上記のテストを実行するだけで、いつ何が起こっているのかを確認できます。
私は時々同じ問題に遭遇します。私は他の言語と同じように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 = 0
がRにある場合、ループに入ることはないと予想しました。ただし、1:0
は有効な数値の範囲です。 if
ループをラップするfor
ステートメントを持つ以外に、良い回避策はまだ見つかりません。
これは、standfordのsna freeチュートリアルに由来し、...
# 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を削除すると問題なく動作します
上記の応答への追加のみ:このような場合、オブジェクトを呼び出している可能性があり、何らかの理由でクエリで使用できません。たとえば、行名または列名でサブセット化できますが、要求された行または列がデータマトリックスまたはデータフレームの一部ではなくなったときに、このエラーメッセージが表示されます。解決策:上記の応答の短いバージョンとして:最後の作業行名または列名を見つける必要があり、次に呼び出されるオブジェクトは見つからなかったものでなければなりません。 「foreach」のような並列コードを実行する場合、コードをforループに変換してトラブルシューティングを行う必要があります。