df <- data.frame(var1 = c('a', 'b', 'c'), var2 = c('d', 'e', 'f'),
freq = 1:3)
Qual é a maneira mais simples de expandir cada linha das duas primeiras colunas do data.frame acima, para que cada linha seja repetida o número de vezes especificado na coluna 'freq'?
Em outras palavras, vá a partir disso:
df
var1 var2 freq
1 a d 1
2 b e 2
3 c f 3
Para isso:
df.expanded
var1 var2
1 a d
2 b e
3 b e
4 c f
5 c f
6 c f
data.frame
mais eficiente é substituirrow.names(df)
porseq.int(1,nrow(df))
ouseq_len(nrow(df))
.pergunta antiga, novo verbo em tidyverse:
fonte
Use a
expandRows()
partir dosplitstackshape
pacote:Sintaxe simples, muito rápida, funciona em
data.frame
oudata.table
.Resultado:
fonte
A solução do @ neilfws funciona muito bem para
data.frame
s, mas não paradata.table
s, pois eles não possuem arow.names
propriedade. Essa abordagem funciona para ambos:O código para
data.table
é um pouco mais limpo:fonte
df[rep(seq(.N), freq)][, freq := NULL]
df[rep(1:.N, freq)][, freq:=NULL]
Caso você precise fazer essa operação em data.frames muito grandes, recomendo convertê-la em uma data.table e use o seguinte, que deve ser executado muito mais rapidamente:
Veja o quão mais rápida é essa solução:
fonte
Error in rep(1, freq) : invalid 'times' argument
. E, como já existe uma resposta da tabela de dados para essa pergunta, você pode descrever como sua abordagem é diferente ou quando é melhor que a resposta atual da tabela de dados. Ou, se não houver uma grande diferença, você poderá adicioná-lo como um comentário à resposta existente.df
da pergunta do OP? Minha resposta é melhor, porque a outra resposta está meio que abusando dodata.table
pacote usando adata.frame
sintaxe, consulte as Perguntas frequentes dedata.table
: "Geralmente é uma prática ruim se referir às colunas por número e não por nome".df
postado pelo OP, mas quando tentei comparar isso em um data.frame maior, recebi esse erro. O data.frame que usei foi: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))
No minúsculo data.frame, a resposta básica funciona bem nos meus benchmarking, mas não se adapta bem a data.frames maiores. As outras três respostas foram bem-sucedidas com esse data.frame maior.data.table
sintaxe, não deveria ser eu quem julgaria as respostas.Outra
dplyr
alternativa com aslice
qual repetimos o número de cada linhafreq
vezesseq_len(n())
A peça pode ser substituída por qualquer um dos seguintes.fonte
Outra possibilidade é usar
tidyr::expand
:Versão de uma linha da resposta de vonjd :
Criado em 2019-05-21 pelo pacote reprex (v0.2.1)
fonte
Sei que esse não é o caso, mas se você precisar manter a coluna freq original, poderá usar outra
tidyverse
abordagem junto comrep
:Criado em 2019-12-21 pelo pacote reprex (v0.3.0)
fonte
.remove = FALSE
emuncount()