下标越界 – 一般定义和解决scheme?

在与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 

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

然而,我的问题不是关于这段代码(即使这也可能有帮助),但是我的问题是更一般的:

  • 下标超出界限的定义是什么? 是什么造成的?
  • 是否有任何通用的方法来处理这种错误?

这是因为你试图从他的边界访问一个数组。 我会告诉你如何debugging这样的错误。

  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. 我input1,我得到

      Called from: top level 
  4. 我inputls()来查看我的当前variables

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

现在我将看到我的variables的维度:

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

你看到改变是越界了。 22> 21。 在行中:

  reach_mat[i, alter] = 1 

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

  • 尝试使用applyxx函数。 他们比安全更安全
  • 我使用seq_along而不是1:n(1:0)
  • 如果可以避免mat [i,j]索引访问,请尝试在向量化解决scheme中考虑。

编辑vector化的解决scheme

例如在这里我看到你不使用set.vertex.attribute是vector化的事实。 您可以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]) } } 

这样:

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

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

只要运行上面的testing,看看发生了什么和什么时候。

我有时遇到同样的问题。 我只能回答你的第二个问题,因为我不像R和其他语言一样熟练。 我发现循环的标准有一些意想不到的结果。 说x = 0

 for (i in 1:x) { print(i) } 

输出是

 [1] 1 [1] 0 

而用python,例如

 for i in range(x): print i 

什么也没做。 循环未input。

我期望,如果在R中x = 0 ,循环将不会被input。 但是, 1:0是一个有效的数字范围。 我还没有find一个很好的解决方法,除了包含for循环的if语句

这来自斯坦福德的免费教程,它指出…

# Reachability can only be computed on one vertex at a time. To # 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, # get graph-wide statistics, change the value of "vertex" # manually or write a for loop. (Remember that, unlike R objects, # get graph-wide statistics, change the value of "vertex" # manually or write a for loop. (Remember that, unlike R objects, # manually or write a for loop. (Remember that, unlike R objects, # igraph objects are numbered from 0.)

好的,所以当使用igraph时,第一个滚动/列是0而不是1,但matrix从1开始,因此对于在igraph下的任何计算,您将需要x-1,如

this_node_reach <- subcomponent(g, (i - 1), mode = m)

但是对于计算,这里有一个错字

alter = this_node_reach[j] + 1

删除+1,它会工作正常

除了上面的回答之外:在这种情况下可能的情况是您正在调用一个对象,出于某种原因,您的查询不可用。 例如,您可以按行名称或列名称进行子集划分,而当您请求的行或列不再是数据matrix或数据框的一部分时,您将收到此错误消息。 解决scheme:作为上述响应的简短版本:您需要查找最后一个工作行名称或列名称,下一个被调用的对象应该是找不到的。 如果你运行像“foreach”这样的并行代码,那么你需要将你的代码转换为一个for循环来排除故障。