/ / Contraer texto por grupo en el marco de datos [duplicado] - r

Contraer texto por grupo en el marco de datos [duplicado] - r

¿Cómo agrego marco de datos por grupo en columna? group y contraer texto en columna text?

Data de muestra:

df <- read.table(header=T, text="
group text
a a1
a a2
a a3
b b1
b b2
c c1
c c2
c c3
")

Salida requerida (marco de datos):

group text
a     a1a2a3
b     b1b2
c     c1c2c3

Ahora tengo:

sapply(unique(df$group), function(x) {
paste0(df[df$group==x,"text"], collapse="")
})

Esto funciona en cierta medida ya que devuelve el texto correctamente colapsado por grupo, pero como un vector:

[1] "a1a2a3" "b1b2"   "c1c2c3"

Necesito un marco de datos con group columna como resultado.

Respuestas

21 para la respuesta № 1

Simplemente usar aggregate :

aggregate(df$text, list(df$group), paste, collapse="")
##   Group.1      x
## 1       a a1a2a3
## 2       b   b1b2
## 3       c c1c2c3

O con plyr

library(plyr)
ddply(df, .(group), summarize, text=paste(text, collapse=""))
##   group   text
## 1     a a1a2a3
## 2     b   b1b2
## 3     c c1c2c3

ddply es más rápido que aggregate Si tienes un gran conjunto de datos.

EDITAR : Con la sugerencia de @SeDur:

aggregate(text ~ group, data = df, FUN = paste, collapse = "")
##   group   text
## 1     a a1a2a3
## 2     b   b1b2
## 3     c c1c2c3

Para el mismo resultado con el método anterior tienes que hacer:

aggregate(x=list(text=df$text), by=list(group=df$group), paste, collapse="")

EDIT2 : Con data.table :

library("data.table")
dt <- as.data.table(df)
dt[, list(text = paste(text, collapse="")), by = group]
##    group   text
## 1:     a a1a2a3
## 2:     b   b1b2
## 3:     c c1c2c3

9 para la respuesta № 2

Puedes usar el paquete dplyr para esto

library(dplyr)

df %>%
group_by(group) %>%
summarise(text=paste(text,collapse=""))