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.framemás eficiente es reemplazarrow.names(df)conseq.int(1,nrow(df))oseq_len(nrow(df)).vieja pregunta, nuevo verbo en tidyverse:
fuente
Uso
expandRows()delsplitstackshapepaquete:Sintaxis simple, muy rápida, funciona en
data.frameodata.table.Resultado:
fuente
La solución de @neilfws funciona muy bien para
data.frames, pero no paradata.tables ya que carecen de larow.namespropiedad. Este enfoque funciona para ambos:El código para
data.tablees 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.dfde la pregunta del OP? Mi respuesta es mejor porque la otra respuesta es mal uso deldata.tablepaquete mediante el uso de ladata.framesintaxis, consulte las preguntas frecuentes dedata.table: "Generalmente es una mala práctica referirse a las columnas por número en lugar de por nombre".dfpublicada 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.tablesintaxis, así que no debería ser yo quien juzgue las respuestas.Otra
dplyralternativa conslicedonde repetimos cada número de filafreqvecesseq_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
tidyverseenfoque junto conrep:Creado en 2019-12-21 por el paquete reprex (v0.3.0)
fuente
.remove = FALSEenuncount()