下标超出界限 - 一般定义和解决方案?

his*_*eim 48 r matrix sna

经常使用RI时,会收到错误消息"下标超出范围".例如:

# 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
Run Code Online (Sandbox Code Playgroud)

这会生成以下错误Error in reach_mat[i, alter] = 1 : subscript out of bounds.

但是,我的问题不是关于这段特殊的代码(即使解决它也有帮助),但我的问题更为笼统:

  • 下标 - 越界错误的定义是什么?是什么导致的?
  • 有没有通用的方法来处理这种错误?

ags*_*udy 78

这是因为您尝试从其边界外访问数组.

我将向您展示如何调试此类错误.

  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")
    
    Run Code Online (Sandbox Code Playgroud)
  3. 我输入1,我得到

     Called from: top level 
    
    Run Code Online (Sandbox Code Playgroud)
  4. 我键入ls()以查看当前变量

      1] "*tmp*"           "alter"           "g"               
         "i"               "j"                     "m"              
        "reach_mat"       "this_node_reach"
    
    Run Code Online (Sandbox Code Playgroud)

现在,我将看到变量的维度:

Browse[1]> i
[1] 1
Browse[1]> j
[1] 21
Browse[1]> alter
[1] 22
Browse[1]> dim(reach_mat)
[1] 21 21
Run Code Online (Sandbox Code Playgroud)

你看到改变是出界的.22> 21.在线:

  reach_mat[i, alter] = 1
Run Code Online (Sandbox Code Playgroud)

为了避免这样的错误,我个人这样做:

  • 尝试使用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])
    }
}
Run Code Online (Sandbox Code Playgroud)

这样:

##  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])
Run Code Online (Sandbox Code Playgroud)

  • 非常有用,这个调试的东西.我的情况,它让我发现"下标越界"错误显然是由于我使用"因子"而不是字符来按名称访问矩阵列.`as.character`解决了我的问题.奇怪的是,有问题的代码是我成功用于类似数据的库的一部分. (4认同)

Jan*_*ary 5

它只是意味着 或alter > ncol( reach_mat )i > nrow( reach_mat )换句话说,您的索引超出了数组边界(i 大于行数,或者 alter 大于列数)。

只需运行上述测试即可查看发生了什么以及何时发生。