2011-09-01 11 views
6

tomando un ejemplo de An Introduction to RDangerous for loop idiom?

xc <- split(x, ind) 
yc <- split(y, ind) 
for (i in 1:length(yc)) { 
    plot(xc[[i]], yc[[i]]) 
    abline(lsfit(xc[[i]], yc[[i]])) 
} 

Parece que for(i in 1:length(yc)) { ... es un modismo para iterar sobre una lista o vector en el caso en que necesita una manija en el índice actual. Sin embargo, esto se rompe en el caso de una lista vacía ya que 1:0 no es un vector vacío. ¿Cuál es el modismo que debería usar para iterar sobre los índices de lista/vector cuando no se garantiza una lista no vacía? Estoy pensando if(length(yc)) for(i in 1:length(yc)) { ..., pero ¿hay una manera más agradable?

Respuesta

11

Está buscando seq_along.

> seq_along(as.list(1:2)) 
[1] 1 2 
> seq_along(list()) 
integer(0) 
+0

exactamente lo que estaba buscando – Keith

+2

... y use 'seq_len' cuando ya tiene la longitud ... – Tommy

7

Puede utilizar seq_along:

for(i in seq_along(yc)) {...} 

estoy bastante seguro de que esto no pasa por el problema y debe ser un poquito más rápido.

+0

gracias Nick (obtuve dos buenas respuestas casi al mismo tiempo) – Keith

4

este punto se encuentra en la página 75 de 'El R Inferno': http://www.burns-stat.com/pages/Tutor/R_inferno.pdf

Se da a conocer algunas otras maneras de conseguir su bucle mal también.

+0

¡Bienvenido a StackOverflow! Encontrarás que el infierno R se tiene en alta estima aquí. Es un gran recurso, gracias! – Aaron

0

Para cualquier persona que se tropiece con esto, si desea un vector de índice basado posiblemente en la longitud cero, en lugar de otro vector, puede usar seq(1, length.out = L), donde L puede ser cualquier número entero no negativo. Eso le dará integer(0) si L == 0 y 1:L de lo contrario.

Por supuesto, las otras soluciones dadas aquí son más concisas si L == length(something), pero tuve un problema donde no era el caso, así que pensé en escribirlo para la progenie.

También seq(1, length.out = L) se puede abreviar como seq_len(L), que según ?seq es más rápido.