Subscript buiten de grenzen – algemene definitie en oplossing?

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.

  1. Ik heb options(error=recover)
  2. ingesteld

  3. 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")
    
  4. Ik voer 1 in en ik krijg

    Called from: top level 
    
  5. Ik typ ls()om mijn huidige variabelen te zien

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

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 applyxxte gebruiken. Ze zijn veiliger dan for
  • Ik gebruik seq_alongen niet 1: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.attributegevectoriseerd 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 = 0dat in R, de lus niet zou worden ingevoerd. 1:0is 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’.

Other episodes