Als ik met R werk, krijg ik regelmatig de foutmelding “subscript out of bounds”. Bijvoorbeeld:
# 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
Dit genereert de volgende fout Error in reach_mat[i, alter] = 1 : subscript out of bounds
.
Mijn vraag gaat echter niet over dit specifieke stukje code (hoewel het ook handig zou zijn om dat ook op te lossen), maar mijn vraag is meer algemeen:
- Wat is de definitie van een subscript-out-of-bounds-fout? Wat veroorzaakt het?
- Zijn er algemene manieren om dit soort fouten te benaderen?
Antwoord 1, autoriteit 100%
Dit komt omdat u probeert toegang te krijgen tot een array buiten zijn begrenzing.
Ik zal u laten zien hoe u dergelijke fouten kunt debuggen.
- Ik heb
options(error=recover)
-
Ik voer
reach_full_in <- reachability(krack_full, 'in')
uit
Ik krijg: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")
-
Ik voer 1 in en ik krijg
Called from: top level
-
Ik typ
ls()
om mijn huidige variabelen te zien1] "*tmp*" "alter" "g" "i" "j" "m" "reach_mat" "this_node_reach"
ingesteld
Nu zal ik de afmetingen van mijn variabelen zien:
Browse[1]> i
[1] 1
Browse[1]> j
[1] 21
Browse[1]> alter
[1] 22
Browse[1]> dim(reach_mat)
[1] 21 21
Je ziet dat alter verboden is. 22 > 21 . in de rij :
reach_mat[i, alter] = 1
Om dergelijke fouten te voorkomen, doe ik persoonlijk dit:
- Probeer de functie
applyxx
te gebruiken. Ze zijn veiliger danfor
- Ik gebruik
seq_along
en niet1:n
(1:0) - Probeer zo mogelijk in een gevectoriseerde oplossing te denken om
mat[i,j]
toegang tot de index te vermijden.
EDIT vectoriseer de oplossing
Hier zie ik bijvoorbeeld dat je geen gebruik maakt van het feit dat set.vertex.attribute
gevectoriseerd is.
U kunt vervangen:
# 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])
}
}
door dit:
## 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])
Antwoord 2, autoriteit 4%
Alleen een aanvulling op de bovenstaande reacties: Een mogelijkheid in dergelijke gevallen is dat u een object aanroept, dat om de een of andere reden niet beschikbaar is voor uw zoekopdracht. U kunt bijvoorbeeld subsets maken op rijnamen of kolomnamen, en u krijgt deze foutmelding wanneer uw gevraagde rij of kolom geen deel meer uitmaakt van de datamatrix of het dataframe.
Oplossing: als een korte versie van de bovenstaande antwoorden: u moet de laatste werkende rijnaam of kolomnaam vinden en het volgende aangeroepen object moet het object zijn dat niet kon worden gevonden.
Als u parallelle codes zoals “foreach” uitvoert, moet u uw code converteren naar een for-lus om problemen op te lossen.
Antwoord 3, autoriteit 3%
Het betekent alleen dat alter > ncol( reach_mat )
of i > nrow( reach_mat )
, met andere woorden, uw indices overschrijden de arraygrens (i is groter dan het aantal rijen, of alter is groter dan het aantal kolommen).
Voer gewoon de bovenstaande tests uit om te zien wat en wanneer er gebeurt.
Antwoord 4, autoriteit 3%
Als dit iemand helpt, ik ben dit tegengekomen tijdens het gebruik van purr::map() met een functie die ik heb geschreven en die ongeveer zo was:
find_nearby_shops <- function(base_account) {
states_table %>%
filter(state == base_account$state) %>%
left_join(target_locations, by = c('border_states' = 'state')) %>%
mutate(x_latitude = base_account$latitude,
x_longitude = base_account$longitude) %>%
mutate(dist_miles = geosphere::distHaversine(p1 = cbind(longitude, latitude),
p2 = cbind(x_longitude, x_latitude))/1609.344)
}
nearby_shop_numbers <- base_locations %>%
split(f = base_locations$id) %>%
purrr::map_df(find_nearby_shops)
Ik kreeg deze foutmelding soms bij samples, maar meestal niet. De oorzaak van het probleem is dat sommige staten in de base_locations-tabel (PR) niet bestonden in de staten_table, dus in wezen had ik alles eruit gefilterd en een lege tabel doorgegeven om te muteren. De moraal van het verhaal is dat je misschien een gegevensprobleem hebt en niet (alleen) een codeprobleem (dus misschien moet je je gegevens opschonen.)
Bedankt voor agstudy en zx8754’s antwoorden hierboven voor je hulp bij het debuggen.
Antwoord 5, autoriteit 2%
Ik kom soms hetzelfde probleem tegen. Ik kan alleen uw tweede opsommingsteken beantwoorden, omdat ik niet zo deskundig ben in R als met andere talen. Ik heb ontdekt dat de standaard for
-lus enkele onverwachte resultaten heeft. Zeg x = 0
for (i in 1:x) {
print(i)
}
De uitvoer is
[1] 1
[1] 0
Terwijl met python, bijvoorbeeld
for i in range(x):
print i
doet niets. De lus wordt niet ingevoerd.
Ik verwachtte dat als x = 0
dat in R, de lus niet zou worden ingevoerd. 1:0
is echter een geldige reeks getallen. Ik heb nog geen goede oplossing gevonden behalve een if
-instructie die de for
-lus
omhult
Antwoord 6
Dit kwam uit de gratis tutorial van standford
en er staat dat …
# 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,
# igraph objects are numbered from 0.)
ok, dus als je igraph gebruikt, is de eerste rol/kolom 0 anders dan 1, maar de matrix begint bij 1, dus voor elke berekening onder igraph heb je x-1 nodig, weergegeven bij
this_node_reach <- subcomponent(g, (i - 1), mode = m)
maar voor de alter-berekening staat hier een typfout
alter = this_node_reach[j] + 1
verwijder +1 en het werkt goed
Antwoord 7
Wat het voor mij deed, was teruggaan in de code en controleren op fouten of onzekere wijzigingen en me concentreren op ‘need-to-have’ in plaats van ‘nice-to-have’.