185 votes

Répéter chaque ligne de data.frame le nombre de fois spécifié dans une colonne

df <- data.frame(var1 = c('a', 'b', 'c'), var2 = c('d', 'e', 'f'),
                 freq = 1:3)

Quelle est la manière la plus simple de développer chaque ligne et les deux premières colonnes du data.frame ci-dessus, de sorte que chaque ligne soit répétée le nombre de fois spécifié dans la colonne "freq" ?

En d'autres termes, partez de là :

df
  var1 var2 freq
1    a    d    1
2    b    e    2
3    c    f    3

A cela :

df.expanded
  var1 var2
1    a    d
2    b    e
3    b    e
4    c    f
5    c    f
6    c    f

194voto

neilfws Points 3881

Voici une solution :

df.expanded <- df[rep(row.names(df), df$freq), 1:2]

Résultat :

    var1 var2
1      a    d
2      b    e
2.1    b    e
3      c    f
3.1    c    f
3.2    c    f

96voto

einar Points 1277

Vieille question, nouveau verbe dans le tidyverse :

library(tidyr) # version >= 0.8.0
df <- data.frame(var1=c('a', 'b', 'c'), var2=c('d', 'e', 'f'), freq=1:3)
df %>% 
  uncount(freq)

    var1 var2
1      a    d
2      b    e
2.1    b    e
3      c    f
3.1    c    f
3.2    c    f

48voto

Sam Firke Points 8843

Utilisation expandRows() de la splitstackshape l'emballage :

library(splitstackshape)
expandRows(df, "freq")

Syntaxe simple, très rapide, fonctionne sur data.frame o data.table .

Résultat :

    var1 var2
1      a    d
2      b    e
2.1    b    e
3      c    f
3.1    c    f
3.2    c    f

26voto

Max Ghenis Points 400

La solution de @neilfws fonctionne très bien pour data.frame mais pas pour les data.table puisqu'ils ne disposent pas de la row.names propriété. Cette approche fonctionne pour les deux :

df.expanded <- df[rep(seq(nrow(df)), df$freq), 1:2]

Le code pour data.table est un peu plus propre :

# convert to data.table by reference
setDT(df)
df.expanded <- df[rep(seq(.N), freq), !"freq"]

7voto

Ronak Shah Points 24715

Autre dplyr alternative avec slice où nous répétons chaque numéro de ligne freq fois

library(dplyr)

df %>%  
  slice(rep(seq_len(n()), freq)) %>% 
  select(-freq)

#  var1 var2
#1    a    d
#2    b    e
#3    b    e
#4    c    f
#5    c    f
#6    c    f

seq_len(n()) peut être remplacée par l'un des éléments suivants.

df %>% slice(rep(1:nrow(df), freq)) %>% select(-freq)
#Or
df %>% slice(rep(row_number(), freq)) %>% select(-freq)
#Or
df %>% slice(rep(seq_len(nrow(.)), freq)) %>% select(-freq)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X