df <- data.frame(var1 = c('a', 'b', 'c'), var2 = c('d', 'e', 'f'),
freq = 1:3)
¿Cuál es la forma más simple de expandir cada fila las dos primeras columnas del data.frame anterior, para que cada fila se repita el número de veces especificado en la columna 'freq'?
En otras palabras, pasa de esto:
df
var1 var2 freq
1 a d 1
2 b e 2
3 c f 3
A esto:
df.expanded
var1 var2
1 a d
2 b e
3 b e
4 c f
5 c f
6 c f
data.frame
más eficiente es reemplazarrow.names(df)
conseq.int(1,nrow(df))
oseq_len(nrow(df))
.vieja pregunta, nuevo verbo en tidyverse:
fuente
Uso
expandRows()
delsplitstackshape
paquete:Sintaxis simple, muy rápida, funciona en
data.frame
odata.table
.Resultado:
fuente
La solución de @neilfws funciona muy bien para
data.frame
s, pero no paradata.table
s ya que carecen de larow.names
propiedad. Este enfoque funciona para ambos:El código para
data.table
es un poco más limpio:fuente
df[rep(seq(.N), freq)][, freq := NULL]
df[rep(1:.N, freq)][, freq:=NULL]
En caso de que tenga que hacer esta operación en data.frames muy grandes, recomendaría convertirlo en data.table y usar lo siguiente, que debería ejecutarse mucho más rápido:
Vea qué tan rápida es esta solución:
fuente
Error in rep(1, freq) : invalid 'times' argument
. Y dado que ya hay una respuesta data.table a esta pregunta, es posible que desee describir cómo su enfoque es diferente o cuándo es mejor que la respuesta data.table actual. O si no hay una diferencia importante, puede agregarlo como un comentario a la respuesta existente.df
de la pregunta del OP? Mi respuesta es mejor porque la otra respuesta es mal uso deldata.table
paquete mediante el uso de ladata.frame
sintaxis, consulte las preguntas frecuentes dedata.table
: "Generalmente es una mala práctica referirse a las columnas por número en lugar de por nombre".df
publicada por el OP, pero cuando intenté comparar esto en un marco de datos más grande, obtuve ese error. El data.frame que utilicé fue: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))
en el pequeño data.frame, la respuesta base funciona bien en mi evaluación comparativa, simplemente no escala bien a data.frames más grandes. Las otras tres respuestas se ejecutaron con éxito con este marco de datos más grande.data.table
sintaxis, así que no debería ser yo quien juzgue las respuestas.Otra
dplyr
alternativa conslice
donde repetimos cada número de filafreq
vecesseq_len(n())
parte se puede reemplazar con cualquiera de los siguientes.fuente
Otra posibilidad es usar
tidyr::expand
:Versión de una sola línea de la respuesta de vonjd :
Creado el 21/05/2019 por el paquete reprex (v0.2.1)
fuente
Sé que este no es el caso, pero si necesita mantener la columna de frecuencia original, puede usar otro
tidyverse
enfoque junto conrep
:Creado en 2019-12-21 por el paquete reprex (v0.3.0)
fuente
.remove = FALSE
enuncount()