Supongamos que usted tiene una trama de datos con el número de filas y número de columnas.

Las columnas tienen nombres. Desea acceder a filas por el número, y las columnas por nombre.

Por ejemplo, uno (posiblemente lento) camino a recorrer las filas es

for (i in 1:nrow(df)) {
  print(df[i, "column1"])
  # do more things with the data frame...
}

Otra manera es crear «listas» para separar las columnas (como column1_list = df[["column1"]), y acceder a las listas en un bucle. Este enfoque puede ser rápido, pero también un inconveniente si desea acceder a muchas columnas.

Hay una manera rápida de recorrer las filas de una trama de datos? Algún otro tipo de estructura de datos mejor para el bucle rápido?

  • Cómo es esto diferente de df[, «columna1»]? También ver ?aplicar con margen = 1.
  • El ejemplo no era lo que yo realmente quería hacer. Yo quería escribir algunos valores en el marco de datos como datos en un archivo de javascript. +1 para la información acerca de «margen» en «aplicar».
  • Yo necesitaba para recorrer las filas para mover en torno a los valores en las columnas bajo situaciones particulares. Me acordé de que la mejor manera de hacer esto en R es: stackoverflow.com/questions/7746567/…

3 Comentarios

  1. 14

    Creo que tengo que hacer de esto una respuesta completa, porque me parece los comentarios más difícil de rastrear y ya he perdido un comentario sobre esto… Hay un ejemplo por nullglob que pone de manifiesto las diferencias entre por y aplicar las funciones de la familia, mucho mejor que los otros ejemplos. Cuando uno hace la función de tal manera que es muy lento, a continuación, que es donde está toda la velocidad que se consume y no encontrar diferencias entre las variaciones en el bucle. Pero cuando usted hace la función trivial, entonces usted puede ver lo mucho que el bucle de influencias cosas.

    También me gustaría añadir que algunos de los miembros de la aplicar familia inexplorado en otros ejemplos interesantes propiedades de rendimiento. Primero voy a mostrar repeticiones de nullglob relativa resultados en mi máquina.

    n <- 1e6
    system.time(for(i in 1:n) sinI[i] <- sin(i))
      user  system elapsed 
     5.721   0.028   5.712 
    
    lapply runs much faster for the same result
    system.time(sinI <- lapply(1:n,sin))
       user  system elapsed 
      1.353   0.012   1.361 

    También encontró sapply mucho más lento. Aquí hay algunos otros que no fueron probados.

    El viejo y simple se aplican a una matriz de versión de los datos…

    mat <- matrix(1:n,ncol =1),1,sin)
    system.time(sinI <- apply(mat,1,sin))
       user  system elapsed 
      8.478   0.116   8.531 

    Así, el apply() comando en sí es mucho más lenta que la del bucle for. (para el bucle no se reduce sensiblemente si puedo usar el pecado(mat[i,1]).

    Otro que no parece ser probado en otros posts es tapply.

    system.time(sinI <- tapply(1:n, 1:n, sin))
       user  system elapsed 
     12.908   0.266  13.589 

    Por supuesto, uno nunca podría usar tapply esta manera y es de utilidad va mucho más allá de cualquier problema de la velocidad en la mayoría de los casos.

    • +1 para la referencia a nullglob. Su cargo tiene una referencia al artículo «¿Cómo puedo Evitar Este Bucle o hacerlo más Rápido?», por Uwe Ligges y John Fox, en «R Noticias», de Mayo de 2008. Gracias por escribir sobre el aplicar funciones.
  2. 12

    La forma más rápida es bucle no (es decir, vectorizados de las operaciones). Uno de los pocos casos en los que usted necesita para bucle es cuando hay dependencias (es decir, una iteración depende de la otra). De lo contrario, tratar de hacer lo más vectorizados de computación fuera del bucle como sea posible.

    Si hacer necesidad de bucle, a continuación, utilizando una for bucle es esencialmente tan rápido como cualquier otra cosa (lapply puede ser un poco más rápido, pero otros aplicar funciones tienden a ser en torno a la misma velocidad como para).

    • Tal vez no hay manera de evitar el bucle para lo que yo quería hacer—ver mi respuesta a Greg comentario anterior.
    • «en torno a la misma velocidad»? Has leído todas las respuestas? En mi respuesta, me muestran que el uso de vapply es 3 veces más rápido (por ejemplo) que el bucle for…
    • En términos de eficiencia algorítmica, son muy similares en velocidad: algorítmica eficiencia
    • vectorizados versión no ser más eficiente que la for-loop versión, gracias @Shane
  3. 0

    Aprovechando el hecho de que los datos.los marcos son esencialmente las listas de vectores columna, uno puede hacer.llame para aplicar una función con la arity de que el número de columnas en cada columna de los datos.marco (similar a un «cierre» a través de una lista en otros idiomas).

    do.call(paste, data.frame(x=c(1,2), z=c("a","b"), z=c(5,6)))
    • Pero eso no es un bucle.

Dejar respuesta

Please enter your comment!
Please enter your name here