2012-06-20 290 views
49

Quiero repetir las filas de un data.frame, cada N veces. El resultado debe ser un nuevo data.frame (con nrow(new.df) == nrow(old.df) * N) manteniendo los tipos de datos de las columnas.Repetir filas de un data.frame

ejemplo para N = 2:

     A B C 
    A B C    1 j i 100 
1 j i 100  -->  2 j i 100 
2 K P 101    3 K P 101 
         4 K P 101 

Así, cada fila se repite 2 veces y los personajes siguen siendo personajes, factores siguen siendo factores, siendo los valores numéricos numéricos, ...

Mi primer intento de utilizar aplican : apply(old.df, 2, function(co) rep(co, each = N)), pero éste se transforma mis valores de caracteres y consigo:

 A B C  
[1,] "j" "i" "100" 
[2,] "j" "i" "100" 
[3,] "K" "P" "101" 
[4,] "K" "P" "101" 
+0

duplicado Posible de [Repetir data.frame N veces] (http://stackoverflow.com/questions/8753531/repeat-data-frame-n-times) –

Respuesta

84
df <- data.frame(a=1:2, b=letters[1:2]) 
df[rep(seq_len(nrow(df)), each=2),] 
+12

Puede usar 'n.times <- c (2,4); df [rep (seq_len (nrow (df)), n.times),] 'si desea variar el número de veces que se repite cada línea. –

4

Si se puede repetir todo el asunto, o un subconjunto primero y luego repetir que, a continuación, this similar question puede ser útil. Una vez más:

library(mefa) 
rep(mtcars,10) 

o simplemente

mefa:::rep.data.frame(mtcars) 
+6

Aha! Otra brillante función R escondida en el interior de un paquete de especialistas seguros con un nombre totalmente diferente. ¡Me encanta este idioma! – smci

4

La función rep.row parece que a veces las listas para las columnas, lo que conduce a malas hijinks memoria. He escrito lo siguiente, que parece funcionar bien:

library(plyr) 
rep.row <- function(r, n){ 
    colwise(function(x) rep(x, n))(r) 
} 
3

Agregando a lo mencionado acerca de @dardisco mefa::rep.data.frame(), es muy flexible.

Puede repita cada fila N veces:

rep(df, each=N) 

o repetición de toda la trama de datos N veces (piensa: como cuando se recicla un argumento vectorizado)

rep(df, times=N) 

Dos ¡Pulgares para arriba para mefa! Nunca había oído hablar de él hasta ahora y tuve que escribir el código manual para hacer esto.

0

Otra forma de hacer esto sería obtener primero índices de fila, anexar copias adicionales del DF, y luego ordenado por los índices:

df$index = 1:nrow(df) 
df = rbind(df,df) 
df = df[order(df$index),][,-ncol(df)] 

Aunque las otras soluciones pueden ser más cortos, este método puede ser más ventajoso en ciertas situaciones.

3

Como referencia y añadiendo a respuestas citando MEFA, puede ser que vale la pena echar un vistazo sobre la aplicación de mefa::rep.data.frame() en caso de que no desee incluir todo el paquete:

> data <- data.frame(a=letters[1:3], b=letters[4:6]) 
> data 
    a b 
1 a d 
2 b e 
3 c f 
> as.data.frame(lapply(data, rep, 2)) 
    a b 
1 a d 
2 b e 
3 c f 
4 a d 
5 b e 
6 c f 
1

Mi solución similar a la mefa:::rep.data.frame , pero un poco más rápido y se preocupa por nombres de las filas:

rep.data.frame <- function(x, times) { 
    rnames <- attr(x, "row.names") 
    x <- lapply(x, rep.int, times = times) 
    class(x) <- "data.frame" 
    if (!is.numeric(rnames)) 
     attr(x, "row.names") <- make.unique(rep.int(rnames, times)) 
    else 
     attr(x, "row.names") <- .set_row_names(length(rnames) * times) 
    x 
} 

comparar soluciones:

library(Lahman) 
library(microbenchmark) 
microbenchmark(
    mefa:::rep.data.frame(Batting, 10), 
    rep.data.frame(Batting, 10), 
    Batting[rep.int(seq_len(nrow(Batting)), 10), ], 
    times = 10 
) 
#> Unit: milliseconds 
#>           expr  min  lq  mean median  uq  max neval cld 
#>    mefa:::rep.data.frame(Batting, 10) 127.77786 135.3480 198.0240 148.1749 278.1066 356.3210 10 a 
#>      rep.data.frame(Batting, 10) 79.70335 82.8165 134.0974 87.2587 191.1713 307.4567 10 a 
#> Batting[rep.int(seq_len(nrow(Batting)), 10), ] 895.73750 922.7059 981.8891 956.3463 1018.2411 1127.3927 10 b 
3

Una solución limpia dplyr, tomada de here

library(dplyr) 
df <- data_frame(x = 1:2, y = c("a", "b")) 
df %>% slice(rep(1:n(), each = 2)) 
Cuestiones relacionadas