grouped dataframe - groupings as facets in a ggplot? - r

Some data
grp_diamonds <- diamonds %>%
group_by(cut) %>%
group_split
grp_diamonds[[1]] %>%
ggplot(aes(x = carat, y = price)) +
geom_point()
This returns a plot for grp_diamonds[[1]]
But grp_diamonds is actually a list of 5 dataframes since I used group_split() earlier.
Is there a clever way to automatically use the groups as facets?
Yes, in this example you could just do this:
diamonds %>%
ggplot(aes(x = carat, y = price)) +
geom_point() +
facet_wrap(vars(cut))
But I wondered if there was a way to automatically facet based on existing groupings?

Making use of dplyr::groups and dplyr::vars and !!!one option would be:
library(dplyr)
library(ggplot2)
grp_diamonds <- diamonds %>%
group_by(cut, color)
grp_diamonds %>%
ggplot(aes(x = carat, y = price)) +
geom_point() +
facet_wrap(facets = vars(!!!groups(grp_diamonds)))

Related

Remove facets from ggplot and instead display on a single chart?

Here is a plot that is very similar to one that I made for a stakeholder:
diamonds %>%
group_by(cut, color) %>%
summarise(av_price = mean(price)) %>%
ggplot(aes(color)) +
geom_bar(aes(weight = av_price)) +
facet_wrap(cut ~ .)
Looks like:
I've been asked to remove the facets and instead display each cut on the same chart but with some space between each (and perhaps each with their own color for readability?)
I do not know how to get this done. Tried:
diamonds %>%
group_by(cut, color) %>%
summarise(av_price = mean(price)) %>%
ggplot(aes(color, cut)) +
geom_bar(aes(weight = av_price))
Error: stat_count() can only have an x or y aesthetic.
How can I display each cut on a single chart as opposed to facets?
How about this solution:
diamonds %>%
group_by(cut, color) %>%
summarise(av_price = mean(price)) %>%
ggplot(aes(color, av_price, fill=cut)) +
geom_col(position="dodge") +
facet_wrap(~cut, nrow=1) +
theme(strip.text.x = element_blank())

Add 2 additional lines to a ggplot

I have successfully plotted my dat below. However, I want to do the following data transformation: dat %>% group_by(groups) %>% mutate(x.cm = mean(x), x.cwc = x-x.cm) and then ADD 2 lines to my current plot:
geom_smooth() using x.cm as x
geom_smooth() using x.cwc as x
Is there a way to do this?
p.s: Is it also possible to display the 3 unique(x.cm) values as 3 stars on the plot? (see pic below)
library(tidyverse)
dat <- read.csv('https://raw.githubusercontent.com/rnorouzian/e/master/cw.csv')
dat %>% group_by(groups) %>% ggplot() +
aes(x, y, color = groups, shape = groups)+
geom_point(size = 2) + theme_classic()+
stat_ellipse()
# Now do the transformation:
dat %>% group_by(groups) %>% mutate(x.cm = mean(x), x.cwc = x-x.cm)
I'm not sure the second part of your question makes any sense to me. But from the description one way is to simply add a level where you alter you data and aes argument, as I do in the example below (using mtcars as an example data)
# Load libraries and data
library(tidyverse)
library(ggplot2)
data(mtcars)
mtcars %>% ggplot(aes(x = hp, y = mpg)) +
geom_point(aes(col = factor(cyl))) +
stat_ellipse(aes(col = factor(cyl))) +
# Add line for ellipsis center
geom_line(data = mtcars %>% group_by(cyl) %>% summarize(mean_x = mean(hp),
mean_y = mean(mpg),
.groups = 'drop'),
mapping = aes(x = mean_x, y = mean_y)) +
geom_point(data = mtcars %>% group_by(cyl) %>% summarize(mean_x = mean(hp),
mean_y = mean(mpg),
.groups = 'drop'),
mapping = aes(x = mean_x, y = mean_y)) +
# Add smooth for.. what? I don't understand this part of the question.
geom_smooth(data = mtcars %>% group_by(cyl) %>% mutate(x_val = hp - mean(hp)) %>% ungroup(),
mapping = aes(x = x_val, y = mpg))
Now it should be quite clear which part does not make sense to me. Why/what do you mean with the second path (geom_smooth)? Moving the x-axis on the smoother makes no sense to me. Also I took the liberty of changing the definition of the first part, by instead adding the single points of the mean (center of circles) to the plot and connecting the using geom_line.

Ordering geom_bar() without a y defined variable

Is there a way to order the bars in geom_bar() when y is just the count of x?
Example:
ggplot(dat) +
geom_bar(aes(x = feature_1))
I tried using reorder() but it requires a defined y variable within aes().
Made up data:
dfexmpl <- data.frame(stringsAsFactors = FALSE,
group = c("a","a","a","a","a","a",
"a","a","a","b","b","b","b","b","b","b","b","b",
"b","b","b","b","b","b"))
plot code - reorder is doing the work of arranging by count:
dfexmpl %>%
group_by(group) %>%
mutate(count = n()) %>%
ggplot(aes(x = reorder(group, -count), y = count)) +
geom_bar(stat = "identity")
results in:

Sort ggplot facet_wrap by color?

I would like to sort by ggplot facet_wrap by color.
For example, in this demo code, the color corresponds to groups A, B, C. I am looking to have all the red plots next to each other, and same for the blue and green plots.
I tried sorting my data by group but ggplot seems to switch the order when plotting.
library(tidyverse)
set.seed(42)
# Generate example data frame
id <- 1:15
data <- map(id, ~rnorm(10))
date <- map(id, ~1:10)
group <- map_chr(id, ~sample(c('a','b','c'), size=1))
df <- tibble(id=id, data=data, date=date, group=group) %>% unnest(cols = c(data, date))
# Generate plot
df %>%
arrange(group) %>%
ggplot(mapping = aes(x=date, y=data, color=group)) +
geom_line() +
geom_point() +
facet_wrap(~ id)
This could help:
library(tidyverse)
set.seed(42)
# Generate example data frame
id <- 1:15
data <- map(id, ~rnorm(10))
date <- map(id, ~1:10)
group <- map_chr(id, ~sample(c('a','b','c'), size=1))
df <- tibble(id=id, data=data, date=date, group=group) %>% unnest(cols = c(data, date))
df2 <- df %>% mutate(id=factor(id))%>%
group_by(group) %>%
mutate(N = n()) %>%
ungroup() %>%
mutate(id = fct_reorder(id, N))
# Generate plot
df2 %>%
arrange(group) %>%
ggplot(mapping = aes(x=date, y=data, color=group)) +
geom_line() +
geom_point() +
facet_wrap(~ id)
This would be a way (would have to get rid of the double title though):
df %>%
arrange(group) %>%
ggplot(mapping = aes(x=date, y=data, color=group)) +
geom_line() +
geom_point() +
facet_wrap(~ group + id)

ggplot geom_boxplot color and group variables

I'm trying to make a straightforward boxplot in ggplot. I'm not sure how get a grouping variable and a color/fill variable. I've tried to gather, but that doesn't seem to work. Any thoughts?
library(tidyverse)
# Does not work
mtcars %>%
as_tibble() %>%
ggplot(aes(factor(gear),
mpg,
group = vs)) +
geom_boxplot(aes(fill = as.factor(gear)))
# Does not work either
mtcars %>%
as_tibble() %>%
select(gear, mpg, vs) %>%
gather(key, value, -vs) %>%
ggplot(aes(key,
value)) +
geom_boxplot(aes(color = vs))
I'm not sure this is your intended output (gear as x-axis and fill), but here's a working example:
mtcars %>%
ggplot(
aes(
x = factor(gear),
y = mpg,
color = factor(vs),
fill = factor(gear)
)
) + geom_boxplot()
I've found being explicit when declaring your aesthetic mappings can be helpful when learning ggplot2.
Alternatively:
mtcars %>%
as_tibble() %>%
group_by(vs) %>%
ggplot(aes(factor(gear),
mpg,
fill=as.factor(gear))) +
geom_boxplot()

Resources