df <- data.frame(var1 = c('a', 'b', 'c'), var2 = c('d', 'e', 'f'),
freq = 1:3)
Какой самый простой способ расширить каждую строку на первые два столбца вышеупомянутого data.frame, чтобы каждая строка повторялась количество раз, указанное в столбце '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
data.frame
более эффективным является заменаrow.names(df)
наseq.int(1,nrow(df))
илиseq_len(nrow(df))
.старый вопрос, новый глагол в тидиверсе:
источник
Используйте
expandRows()
изsplitstackshape
пакета:Простой синтаксис, очень быстрый, работает на
data.frame
илиdata.table
.Результат:
источник
Решение @ neilfws прекрасно работает для
data.frame
s, но не дляdata.table
s, так как им не хватаетrow.names
свойства. Этот подход работает для обоих:Код для
data.table
немного чище:источник
df[rep(seq(.N), freq)][, freq := NULL]
df[rep(1:.N, freq)][, freq:=NULL]
Если вам нужно выполнить эту операцию с очень большими data.frames, я бы порекомендовал преобразовать ее в data.table и использовать следующее, которое должно работать намного быстрее:
Посмотрите, насколько быстрее это решение:
источник
Error in rep(1, freq) : invalid 'times' argument
. И, учитывая, что на этот вопрос уже есть ответ data.table, вы можете описать, чем отличается ваш подход или когда он лучше, чем текущий ответ data.table. Или, если нет большой разницы, вы можете добавить его в качестве комментария к существующему ответу.df
из вопроса ОП? Мой ответ лучше, потому что другой ответ является своего рода неправильным использованиемdata.table
пакета с использованиемdata.frame
синтаксиса, см. Раздел часто задаваемых вопросовdata.table
: «Обычно плохая практика - ссылаться на столбцы по номеру, а не по имени».df
опубликованном OP, но когда я попытался сравнить его с большим массивом данных. Я получил эту ошибку. Data.frame, который я использовал, был:set.seed(1) dfbig <- data.frame(var1=sample(letters, 1000, replace = TRUE), var2=sample(LETTERS, 1000, replace = TRUE), freq=sample(1:10, 1000, replace = TRUE))
На крошечном data.frame базовый ответ преуспевает в моем сравнительном тестировании, он просто плохо масштабируется для больших data.frames. Остальные три ответа успешно прошли с этим большим data.frame.data.table
синтаксис, поэтому я не должен судить ответы.Еще один
dplyr
вариант,slice
где мы повторяем число строк каждыйfreq
разseq_len(n())
часть может быть заменена любым из следующих.источник
Другая возможность использует
tidyr::expand
:Однострочная версия ответа Вонда :
Создано 2019-05-21 пакетом представлением (v0.2.1)
источник
Я знаю, что это не так, но если вам нужно сохранить исходный столбец freq, вы можете использовать другой
tidyverse
подход вместе сrep
:Создано в 2019-12-21 с помощью пакета представительства (v0.3.0)
источник
.remove = FALSE
вuncount()