2010-04-01 10 views
15

Estoy tratando de escribir a partir de un bucle de una trama de datos en R, por ejemplo, un circuito como éste>escrito a una trama de datos desde un bucle en el R

for (i in 1:20) { 
print(c(i+i,i*i,i/1))} 

y escribir cada línea de 3 valores a un marco de datos con tres columnas, de modo que cada iteración tome una nueva fila. He intentado usar matrix, con ncol = 3 y rellenado por filas, pero solo obtengo el último elemento del ciclo.

Gracias.

Respuesta

22

Usted podría utilizar rbind:

d <- data.frame() 
for (i in 1:20) {d <- rbind(d,c(i+i, i*i, i/1))} 
+2

Tenga en cuenta que esta es probablemente la solución menos eficiente propuesta. Para conjuntos de datos muy pequeños no importará demasiado, pero no debería usar rbind o cbind dentro de un bucle si quiere ser eficiente. – Dason

4

bucle For tienen efectos secundarios, por lo que la forma habitual de hacer esto es crear una trama de datos vacía antes del bucle y luego añadir a la misma en cada iteración. Puede instanciarlo al tamaño correcto y luego asignar sus valores a la fila i en cada iteración, o bien agregarlo y reasignar todo usando rbind().

El primer enfoque tendrá un mejor rendimiento para grandes conjuntos de datos.

+0

Gracias por estas dos respuestas, asignar valores a la i-ésima fila significa algo así, (esto en realidad no funciona). Además, ¿funcionaría así con un marco de datos con un número desconocido de filas? rm (d) d <- data.frame (nrow = 20, ncol = 3) para (i en 1:20) { d [i,] <- c (i + i, i * i, i/1)} – CCID

+0

¿Por qué dices "número de filas desconocidas" cuando tu ejemplo tiene I en 1:20? Si hay un número desconocido de filas, necesitará usar algo como rbind como sugiere otra respuesta. –

6

Si todos los valores tienen el mismo tipo y que conoce el número de filas, puede utilizar una matriz de la siguiente manera (esto será muy rápido):

d <- matrix(nrow=20, ncol=3) 
for (i in 1:20) { d[i,] <- c(i+i, i*i, i/1)} 

Si necesita una trama de datos , puede utilizar rbind (como se sugiere otra respuesta), o funciones de plyr paquete de la siguiente manera:

library(plyr) 
ldply(1:20, function(i)c(i+i, i*i, i/1)) 
10

otra forma sería

do.call("rbind", sapply(1:20, FUN = function(i) c(i+i,i*i,i/1), simplify = FALSE)) 


    [,1] [,2] [,3] 
[1,] 2 1 1 
[2,] 4 4 2 
[3,] 6 9 3 
[4,] 8 16 4 
[5,] 10 25 5 
[6,] 12 36 6 

Si no especifica simplify = FALSE, tiene que transponer el resultado usando t. Esto puede ser tedioso para estructuras grandes.

Esta solución es especialmente útil si tiene un conjunto de datos en el lado grande y/o necesita repetir esto muchas veces.

Ofrezco algunos tiempos de soluciones en este "hilo".

> system.time(do.call("rbind", sapply(1:20000, FUN = function(i) c(i+i,i*i,i/1), simplify = FALSE))) 
    user system elapsed 
    0.05 0.00 0.05 

> system.time(ldply(1:20000, function(i)c(i+i, i*i, i/1))) 
    user system elapsed 
    0.14 0.00 0.14 

> system.time({d <- matrix(nrow=20000, ncol=3) 
+ for (i in 1:20000) { d[i,] <- c(i+i, i*i, i/1)}}) 
    user system elapsed 
    0.10 0.00 0.09 

> system.time(ldply(1:20000, function(i)c(i+i, i*i, i/1))) 
    user system elapsed 
    62.88 0.00 62.99 
+0

'sapply' parece haberse vuelto más rápido (al menos en mi máquina) al escribirlo como sapply (** 1: 2e4 **, FUN = función (i) ** c (2 * i, i^2, i/1) **, simplificar = FALSO) –

Cuestiones relacionadas