agrupar por dos columnas en ggplot2

91

¿Es posible agrupar por dos columnas? Entonces, ¿el producto cruzado es elaborado por geom_point()y geom_smooth()?

Como ejemplo:

frame <- data.frame(
 series <- rep(c('a', 'b'), 6), 
 sample <- rep(c('glass','water', 'metal'), 4), 
 data <- c(1:12))

ggplot(frame, aes()) # ...

De tal manera que los puntos 6y 12comparten un grupo, pero no con 3.

Reactormonk
fuente

Respuestas:

32

¿Por qué no solo pasteesas dos columnas juntas y usar esa variable como grupos?

frame$grp <- paste(frame[,1],frame[,2])

Una forma algo más formal de hacer esto sería usar la función interaction.

joran
fuente
27
Creo que no deberías modificar tu data.framecon el propósito de una trama. El plotdebe trazar su df y no lo contrario.
ClementWalter
3
Estoy de acuerdo, la respuesta de Blue Magister es mejor.
Jeston
6
@clemlaflemme Creo que la respuesta de BlueMagister está bien, aunque creo que la distinción en este caso es bastante menor. Pero la posición general de que uno no debe modificar su marco de datos para una gráfica es curiosa dada su elección de usar ggplot2 , cuyo diseño completo se basa en estructurar explícitamente sus datos para que funcionen con la semántica de ggplot.
joran
Una desventaja de pastees que cuando el input es un factor, descarta los niveles, donde interactionconserva el orden de los factores originales. Esto significa que los grupos están más naturalmente ordenados con interactionenfoque.
Kota Mori
174

Tomando el ejemplo de esta pregunta , usando interactionpara combinar dos columnas en un nuevo factor:

# Data frame with two continuous variables and two factors 
set.seed(0)
x <- rep(1:10, 4)
y <- c(rep(1:10, 2)+rnorm(20)/5, rep(6:15, 2) + rnorm(20)/5)
treatment <- gl(2, 20, 40, labels=letters[1:2])
replicate <- gl(2, 10, 40)
d <- data.frame(x=x, y=y, treatment=treatment, replicate=replicate)

ggplot(d, aes(x=x, y=y, colour=treatment, shape = replicate,
  group=interaction(treatment, replicate))) + 
  geom_point() + geom_line()

ejemplo de ggplot

Magister azul
fuente
Esto funciona para mí:ggplot(df) + geom_violin(aes(class1, metric.var, group = interaction(class1, class2)), position = position_dodge(width=.5))
ivan866
59

por ejemplo:

 qplot(round, price, data=firm, group=id, color=id, geom='line') +  
      geom_smooth(aes(group=interaction(size, type)))
Davoud Taghawi-Nejad
fuente