2012-06-20 20 views
49

Voglio ripetere le righe di un data.frame, ogni N volte. Il risultato dovrebbe essere un nuovo data.frame (con nrow(new.df) == nrow(old.df) * N) mantenendo i tipi di dati delle colonne.Ripetere le righe di un data.frame

Esempio per 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 

Così, ogni riga si ripete 2 volte e personaggi rimangono personaggi, fattori rimangono fattori, numerici rimangono numerici, ...

Il mio primo tentativo usato applicano : apply(old.df, 2, function(co) rep(co, each = N)), ma questo trasforma i miei valori ai caratteri ed ottengo:

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

Eventuali duplicati di [Ripetere data.frame N volte] (http://stackoverflow.com/questions/8753531/repeat-data-frame-n-times) –

risposta

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

È possibile utilizzare 'n.times <- c (2,4); df [rep (seq_len (nrow (df)), n.times),] 'se vuoi variare il numero di volte in cui ogni riga viene ripetuta. –

4

Se si può ripetere il tutto, o un sottoinsieme in primo luogo quindi ripetere che, quindi this similar question può essere utile. Ancora una volta:

library(mefa) 
rep(mtcars,10) 

o semplicemente

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

Aha! Un'altra brillante funzione R nascosta in profondità all'interno di un pacchetto specialistico incerto con un nome totalmente non correlato. Amo questa lingua! – smci

4

La funzione rep.row sembra fare a volte le liste per le colonne, che porta a hijinks memoria difettosi. Ho scritto il seguente, che sembra funzionare bene:

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

Aggiungendo a ciò @dardisco accennato circa mefa::rep.data.frame(), è molto flessibile.

Puoi ripetere ogni riga N volte:

rep(df, each=N) 

o ripetere l'intero dataframe N volte (pensate: come quando si ricicla un argomento vectorized)

rep(df, times=N) 

Two pollice in su per mefa! Non ne avevo mai sentito parlare fino ad ora e ho dovuto scrivere il codice manuale per farlo.

0

Un altro modo per fare questo sarebbe alla prima ottenere indici riga, aggiungere ulteriori copie del df, e poi ordine dagli indici:

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

Sebbene le altre soluzioni possono essere più breve, questo metodo può essere più vantaggioso in determinate situazioni.

3

Per riferimento e l'aggiunta alle risposte citando mefA, potrebbe vale la pena di dare un'occhiata sull'attuazione del mefa::rep.data.frame() nel caso in cui non si vuole includere l'intero pacchetto:

> 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

La mia soluzione simile a mefa:::rep.data.frame , ma un po 'più veloce e si preoccupa nomi di riga:

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 
} 

Confronta soluzioni:

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 dplyr soluzione pulita, tratto da here

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