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

上記の data.frame の最初の 2 列で各行を展開し、列「freq」で指定された回数だけ各行が繰り返されるようにする最も簡単な方法は何ですか?

つまり、次のようになります。

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

これに:

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

9 に答える 9

193

ここに1つの解決策があります:

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

結果:

    var1 var2
1      a    d
2      b    e
2.1    b    e
3      c    f
3.1    c    f
3.2    c    f
于 2010-05-24T05:01:19.610 に答える
48

パッケージexpandRows()から使用:splitstackshape

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

シンプルな構文、非常に高速、またはで動作しdata.frameますdata.table

結果:

    var1 var2
1      a    d
2      b    e
2.1    b    e
3      c    f
3.1    c    f
3.2    c    f
于 2015-05-11T16:18:45.187 に答える
5

非常に大きな data.frames でこの操作を行う必要がある場合は、それを data.table に変換し、以下を使用することをお勧めします。これにより、はるかに高速に実行されるはずです。

library(data.table)
dt <- data.table(df)
dt.expanded <- dt[ ,list(freq=rep(1,freq)),by=c("var1","var2")]
dt.expanded[ ,freq := NULL]
dt.expanded

このソリューションがどれほど高速かを確認してください。

df <- data.frame(var1=1:2e3, var2=1:2e3, freq=1:2e3)
system.time(df.exp <- df[rep(row.names(df), df$freq), 1:2])
##    user  system elapsed 
##    4.57    0.00    4.56
dt <- data.table(df)
system.time(dt.expanded <- dt[ ,list(freq=rep(1,freq)),by=c("var1","var2")])
##    user  system elapsed 
##    0.05    0.01    0.06
于 2015-07-06T10:18:52.747 に答える