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 ответов


это потому, что вы пытаетесь получить доступ к массиву из его границ.

я покажу вам, как вы можете отлаживать такие ошибки.

  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

чтобы избежать такой ошибки, лично я делаю следующее:

  • попробуйте использовать

Это просто означает, что либо 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, чтобы иметь возможность устранить его.