pogrupuj według dwóch kolumn w ggplot2

91

Czy można grupować według dwóch kolumn? Czyli iloczyn krzyżowy jest rysowany przez geom_point()i geom_smooth()?

Jako przykład:

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

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

Taki, że wskazuje 6i 12dzieli grupę, ale nie z 3.

Reactormonk
źródło

Odpowiedzi:

32

Dlaczego nie tylko pastete dwie kolumny razem i użyć tej zmiennej jako grup?

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

Nieco bardziej formalnym sposobem byłoby użycie funkcji interaction.

joran
źródło
27
Myślę, że nie powinieneś modyfikować swojego data.framena potrzeby fabuły. plotNależy wykreślić swoje df, a nie odwrotnie.
ClementWalter
3
Zgadzam się, odpowiedź Blue Magister jest lepsza.
Jeston
6
@clemlaflemme Myślę, że odpowiedź BlueMagister jest w porządku, chociaż myślę, że rozróżnienie w tym przypadku jest dość niewielkie. Ale ogólne stanowisko, że nie powinno się modyfikować ramki danych dla wykresu, jest dziwne, biorąc pod uwagę wybór użycia ggplot2 , którego cały projekt opiera się na jawnej strukturze danych do pracy z semantyką ggplot.
joran
Wadą pastejest to, że kiedy wejście jest czynnikiem, odrzuca poziomy, gdzie interactionzachowuje kolejność pierwotnych czynników. Oznacza to, że grupy są bardziej naturalnie uporządkowane w interactionpodejściu.
Kota Mori
174

Biorąc przykład z tego pytania , używając interactiondo połączenia dwóch kolumn w nowy czynnik:

# 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()

przykład ggplot

Niebieski Magister
źródło
To działa dla mnie:ggplot(df) + geom_violin(aes(class1, metric.var, group = interaction(class1, class2)), position = position_dodge(width=.5))
ivan866
59

na przykład:

 qplot(round, price, data=firm, group=id, color=id, geom='line') +  
      geom_smooth(aes(group=interaction(size, type)))
Davoud Taghawi-Nejad
źródło