Subíndice fuera de límites-definición general y solución?
matrix sna (5)
A veces me encuentro con el mismo problema. Solo puedo responder tu segundo punto, porque no soy tan experto en R como lo soy con otros idiomas. He descubierto que el ciclo estándar for
tiene algunos resultados inesperados. Digamos x = 0
for (i in 1:x) {
print(i)
}
El resultado es
[1] 1
[1] 0
Mientras que con Python, por ejemplo
for i in range(x):
print i
no hace nada. El ciclo no está ingresado.
Esperaba que si x = 0
eso en R, el bucle no sería ingresado. Sin embargo, 1:0
es un rango válido de números. Todavía no he encontrado una buena solución además de tener una declaración if
que envuelve el bucle for
Cuando se trabaja con RI, con frecuencia aparece el mensaje de error "subíndice fuera de límites". Por ejemplo :
# 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
Esto genera el siguiente error Error in reach_mat[i, alter] = 1 : subscript out of bounds
.
Sin embargo, mi pregunta no es sobre este fragmento de código en particular (aunque sería útil resolverlo también), pero mi pregunta es más general:
- ¿Cuál es la definición de un error de subíndice fuera de límites? ¿Qué lo causa?
- ¿Hay alguna forma genérica de abordar este tipo de error?
Esto se debe a que intenta acceder a una matriz fuera de su límite.
Le mostraré cómo puede depurar tales errores.
- Establecí
options(error=recover)
reach_full_in <- reachability(krack_full, ''in'')
obtengo: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")
Entro 1 y obtengo
Called from: top level
ls()
para ver mis variables actuales1] "*tmp*" "alter" "g" "i" "j" "m" "reach_mat" "this_node_reach"
Ahora, veré las dimensiones de mis variables:
Browse[1]> i
[1] 1
Browse[1]> j
[1] 21
Browse[1]> alter
[1] 22
Browse[1]> dim(reach_mat)
[1] 21 21
Ves que el alter está fuera de límites. 22> 21. En la linea :
reach_mat[i, alter] = 1
Para evitar ese error, personalmente hago esto:
- Intenta usar la función
applyxx
. Son más seguros quefor
- Yo uso
seq_along
y no1:n
(1: 0) - Intenta pensar en una solución vectorizada si puedes evitar el acceso al índice
mat[i,j]
.
EDIT vectorizar la solución
Por ejemplo, aquí veo que no usas el hecho de que set.vertex.attribute
está vectorizado.
Puedes reemplazar:
# 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])
}
}
por esto:
## 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])
Esto vino del tutorial gratuito de standford y afirma que ...
# 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,
# manually or write a for loop. (Remember that, unlike R objects,
# igraph objects are numbered from 0.)
bien, entonces cuando se usa igraph, el primer rollo / columna es 0 distinto de 1, pero la matriz comienza en 1, por lo tanto, para cualquier cálculo bajo igraph, necesitaría x-1, que se muestra en
this_node_reach <- subcomponent(g, (i - 1), mode = m)
pero para el cálculo alternativo, hay un error tipográfico aquí
alter = this_node_reach[j] + 1
eliminar +1 y funcionará bien
Simplemente significa que alter > ncol( reach_mat )
o i > nrow( reach_mat )
, en otras palabras, sus índices exceden el límite de la matriz (i es mayor que el número de filas, o alter es mayor que el número de columnas).
Simplemente ejecute las pruebas anteriores para ver qué y cuándo está sucediendo.
Solo una adición a las respuestas anteriores: una posibilidad en tales casos es que llame a un objeto que, por alguna razón, no está disponible para su consulta. Por ejemplo, puede subconjuntar por nombres de filas o columnas, y recibirá este mensaje de error cuando la fila o columna solicitada ya no forma parte de la matriz de datos o el marco de datos. Solución: como una versión corta de las respuestas anteriores: debe encontrar el último nombre o nombre de la columna de trabajo, y el siguiente objeto llamado debería ser el que no se pudo encontrar. Si ejecuta códigos paralelos como "foreach", entonces necesita convertir su código a un bucle for para poder solucionarlo.