下标越界 – 一般定义和解决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这样的错误。
- 我设置
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")
-
我input1,我得到
Called from: top level
-
我input
ls()
来查看我的当前variables1] "*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循环来排除故障。