Subscript out of bounds-общее определение и решение?
при работе с R я часто получаю сообщение об ошибке "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
.
однако мой вопрос не об этом конкретном фрагменте кода (хотя было бы полезно решить и это), но мой вопрос более общий:
- каково определение ошибки индекса вне границ? Чем это вызвано?
- есть ли общие способы подхода к такого рода ошибкам?
5 ответов
это потому, что вы пытаетесь получить доступ к массиву из его границ.
я покажу вам, как вы можете отлаживать такие ошибки.
- я
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
чтобы избежать такой ошибки, лично я делаю следующее:
- попробуйте использовать
Это просто означает, что либо alter > ncol( reach_mat )
или i > nrow( reach_mat )
, другими словами, ваши индексы превышают границу массива (i больше, чем количество строк, или alter больше, чем количество столбцов).
просто запустите тесты, чтобы видеть, что и когда происходит.
Я иногда сталкиваюсь с такой же проблемой. Я могу ответить только на вашу вторую пулю, потому что я не такой эксперт в R, как с другими языками. Я обнаружил, что стандарт 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
цикл
это пришло из бесплатного учебника 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 первый рулон / столбец равен 0, кроме 1, но матрица начинается с 1, поэтому для любого вычисления под igraph вам понадобится x-1, показанный в
this_node_reach <- subcomponent(g, (i - 1), mode = m)
но для расчета alter здесь есть опечатка
alter = this_node_reach[j] + 1
удалить +1 и он будет хорошо работать
только дополнение к приведенным выше ответам: возможность в таких случаях заключается в том, что вы вызываете объект, который по какой-то причине недоступен вашему запросу. Например, вы можете подмножество по именам строк или столбцов, и вы получите это сообщение об ошибке, когда запрошенная строка или столбец больше не является частью Матрицы данных или фрейма данных. Решение: как короткая версия ответов выше: вам нужно найти последнее имя рабочей строки или имя столбца, а следующий вызываемый объект должен быть тем, кого нельзя найти. Если вы запускаете параллельные коды, такие как" foreach", вам нужно преобразовать код в цикл for, чтобы иметь возможность устранить его.