2011-10-12 12 views
10

Volevo vedere se qualcuno ha una soluzione più elegante. Ma qual è il modo appropriato per tenere traccia dell'indice corrente durante l'utilizzo di apply. Ad esempio, supponiamo di voler prendere SOLO la somma dall'elemento corrente che sto valutando andando avanti fino alla fine del mio vettore.Tenere traccia dell'indice corrente quando si applica

È questo il modo migliore per farlo?

y = rep(1,100) 
apply(as.matrix(seq(1:length(y))),1,function(x) { sum(y[x:length(y)])}) 

Apprezzo il tuo contributo.

risposta

8

Questo sembra più un compito per sapply:

sapply(seq_along(y), function(x){sum(y[x:length(y)])}) 

Per esempio specifico, ci sono un sacco di altre opzioni (come invertire il vettore y e quindi utilizzando cumsum), ma credo che questo è il generale schema: utilizzare seq_along o nel peggiore dei casi seq per ottenere la sequenza che ti interessa e passare a *apply.

+1

Solo una domanda per chiarire il problema discusso: non è un ciclo for più pratico se si ha bisogno di un indice? O mi manca il punto qui? – ROLO

+2

@ROLO: la famiglia di funzioni '* apply' tipicamente può fornire una gestione della memoria molto ragionevole per i risultati e li memorizza in una forma pratica se' simplify = TRUE' (che non è così ovvio con questi semplici esempi). Storicamente, era anche così che erano molto più veloci dei cicli "normali", ma non è più vero. Quindi, per casi semplici, non importa troppo. –

+0

+1 per il suggerimento di cessione – Thierry

3

rev(cumsum(y)) sarebbe molto più veloce in questa istanza:

> y = rep(1,100000) 
> system.time(apply(as.matrix(seq(1:length(y))),1,function(x) { sum(y[x:length(y)])})) 
    user system elapsed 
88.108 88.639 176.094 
> system.time(rev(cumsum(y))) 
    user system elapsed 
    0.002 0.001 0.004 
0

Ebbene, l'esempio potrebbe essere stato un po 'sfortunato, ma la questione di come conoscere un indice, mentre nella funzione di "applicare" o "sapply" rimane senza risposta.

Qualcosa si potrebbe voler guardare è

x <- 0 
l <- 1:10; names(l) <- letters[l] 
sapply(l,function(Y) { 
    x <<- x+1 
    a<-sum(x:length(l)) 
    cat("I am at ",names(l)[x]," valued ",a,".\n",sep="") 
    return(a) 
}) 

Sono anche infelice, nonostante il "< < -" trucco per riferimento a variabili esterne (grazie, Stephan). Soprattutto quando si corre in parallelo, si desidera che la semantica sia espressa in modo chiaro e chiaro che richiede l'indice o la posizione x/y in modo discreto o applicato. Le idee migliori sono le benvenute.

Problemi correlati