rmatrixsna

Subscript out of bounds - general definition and solution?


When working with R I frequently get the error message "subscript out of bounds". For example:

# 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

This generates the following error Error in reach_mat[i, alter] = 1 : subscript out of bounds.

However, my question is not about this particular piece of code (even though it would be helpful to solve that too), but my question is more general:


Solution

  • This is because you try to access an array out of its boundary.

    I will show you how you can debug such errors.

    1. I set options(error=recover)
    2. I run reach_full_in <- reachability(krack_full, 'in') I get :

      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. I enter 1 and I get

       Called from: top level 
      
    4. I type ls() to see my current variables

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

    Now, I will see the dimensions of my variables :

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

    You see that alter is out of bounds. 22 > 21 . in the line :

      reach_mat[i, alter] = 1
    

    To avoid such error, personally I do this :

    EDIT vectorize the solution

    For example, here I see that you don't use the fact that set.vertex.attribute is vectorized.

    You can replace:

    # 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])
        }
    }
    

    by this:

    ##  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])