Реплицируйте каждую строку данных.кадр и укажите количество повторов для каждой строки
df <- data.frame(var1=c('a', 'b', 'c'), var2=c('d', 'e', 'f'), freq=1:3)
каков самый простой способ развернуть первые два столбца данных.рамка выше, так что каждая строка отображается количество раз, указанное в столбце '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
5 ответов:
вот одно из решений:
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
использовать
expandRows()
С :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
старый вопрос, новый глагол в 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
решение@neilfws отлично подходит для
data.frame
, а неdata.table
s так как им не хватаетrow.names
собственность. Этот подход работает для обоих:df.expanded <- df[rep(seq(nrow(df)), df$freq), 1:2]
код
data.table
немного чище:# convert to data.table by reference setDT(df) df.expanded <- df[rep(seq(.N), freq), !"freq"]
в случае, если вы должны сделать эту операцию на очень больших данных.кадры я бы рекомендовал преобразовать его в данные.стол и использовать следующие, которые должны работать намного быстрее:
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