2011-10-12 9 views
10

Quería ver si alguien tiene una solución más elegante. Pero, ¿cuál es la forma adecuada de realizar un seguimiento del índice actual mientras se utiliza apply? Por ejemplo, supongamos que quisiera tomar la suma ÚNICAMENTE del elemento actual que estoy evaluando hasta el final de mi vector.Realizando un seguimiento del índice actual al usar aplicar

¿Es esta la mejor manera de hacerlo?

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

Agradezco su opinión.

Respuesta

8

Esto se parece más a una tarea para sapply:

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

Para su ejemplo específico, hay un montón de otras opciones (como revertir el vector y y luego usando cumsum), pero creo que este es el general, patrón: use seq_along o en el peor de los casos seq para obtener la secuencia que le interese y pase esto al *apply.

+1

Sólo una pregunta para aclarar el problema discutido: ¿no es un bucle for más práctico si se necesita un índice? O me estoy perdiendo el punto aquí? – ROLO

+2

@ROLO: la familia de funciones '* apply' generalmente puede proporcionar un manejo de memoria muy razonable para los resultados, y los almacena en una forma práctica si' simplify = TRUE' (que no es tan obvio con estos ejemplos simples). Históricamente, también solía ser de modo que eran mucho más rápidos que los bucles "normales", pero eso ya no es así. Entonces, para casos simples, no importa demasiado. –

+0

+1 para la sugerencia cumsum – Thierry

3

rev(cumsum(y)) sería mucho más rápido en la instancia actual:

> 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

Pues bien, el ejemplo puede haber sido un poco desafortunado, pero la pregunta de cómo aprender acerca de un índice mientras que en la función de "aplicar" o "sapply" sigue sin respuesta.

Algo es posible que desee tener en cuenta es

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) 
}) 

También soy infeliz, a pesar de la "< < -" truco para hacer referencia a variables externas (gracias, Stephan). Especialmente cuando se ejecuta en paralelo, quiere que la semántica exprese de alguna manera claramente que solicite el índice o la posición x/y en sapply o apply. Mejores ideas son bienvenidas.

Cuestiones relacionadas