Reputation: 674
Problem
I've looked at numerous SO questions/R Studio blogs to solve the problem but nothing has helped thus far. I tried using various functions in the reorder() function, creating and using a wide dataset.
https://rstudio-pubs-static.s3.amazonaws.com/7433_4537ea5073dc4162950abb715f513469.html
reorder x-axis variables by sorting a subset of the data
How do I sort a dataframe by the average of subsets of one of the rows?
Output Goal
Each X point has 3 Y values - one is a benchmark. To show how the 2 other points perform, I need to order the benchmark in descending fashion to create a graph like so (red being benchmark):
The above chart is simulated to show the goal. Please ignore the few of the red outlier dots.
Current method
sample.chart <-
ggplot(sample.data, aes(
x = reorder(store, -scaling),
y = scaling,
color=version
)) +
geom_point(alpha = 0.7) +
theme(
axis.text.x = element_blank()
)
How would I be able to 'target' a specific subset to order the chart by?
Data str
> str(sample.data)
Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 60 obs. of 3 variables:
$ store : int 1 2 3 4 5 6 7 8 9 10 ...
$ scaling: num 3.67 17.5 51 7.6 49 ...
$ version: chr "test.1" "test.1" "test.1" "test.1" ...
Data
> dput(sample.data)
structure(list(store = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L,
10L, 11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L, 1L, 2L,
3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 16L,
17L, 18L, 19L, 20L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L,
11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L), scaling = c(3.66666666666667,
17.5, 51, 7.6, 49, 0.333333333333333, 7.25, 13, 1.66666666666667,
9.73333333333333, 0.307692307692308, 0.74468085106383, 5, 1.27272727272727,
0.259259259259259, 0.866666666666667, 2.625, 1.58333333333333,
2.71428571428571, 0.625, 5.5, 35, 51, 9.5, 49, 3, 4.83333333333333,
8.66666666666667, 3.33333333333333, 4.17142857142857, 0.666666666666667,
2.91666666666667, 1.42857142857143, 2.8, 0.424242424242424, 0.8125,
1.82608695652174, 1.72727272727273, 2.375, 0.571428571428571,
66, 62.78461538, 56.1, 53.9, 49.5, 47.3, 39.1, 39.05, 37.2, 30.8,
29.7, 29.15, 28.6, 23.61333333, 20.8, 19.25, 18.61538462, 17.74666667,
17.11111111, 16.8), version = c("test.1", "test.1", "test.1",
"test.1", "test.1", "test.1", "test.1", "test.1", "test.1", "test.1",
"test.1", "test.1", "test.1", "test.1", "test.1", "test.1", "test.1",
"test.1", "test.1", "test.1", "test.2", "test.2", "test.2", "test.2",
"test.2", "test.2", "test.2", "test.2", "test.2", "test.2", "test.2",
"test.2", "test.2", "test.2", "test.2", "test.2", "test.2", "test.2",
"test.2", "test.2", "benchmark", "benchmark", "benchmark", "benchmark",
"benchmark", "benchmark", "benchmark", "benchmark", "benchmark",
"benchmark", "benchmark", "benchmark", "benchmark", "benchmark",
"benchmark", "benchmark", "benchmark", "benchmark", "benchmark",
"benchmark")), .Names = c("store", "scaling", "version"), row.names = c(NA,
-60L), class = c("tbl_df", "tbl", "data.frame"))
Upvotes: 1
Views: 2475
Reputation: 2431
Regardless of how you order the x-axis values, since you keep them as numeric values, ggplot will order them numerically. Instead, you need to turn them into factors, ordered by descending order of the y-value. Factors are technically stored with ordinal values, so ggplot will order the points by those new integer indices instead:
library(dplyr)
library(forcats)
sample.data <- sample.data %>%
arrange(version, desc(scaling)) %>% #benchmark comes first alphabetically, so it will use all of those values first for sorting
mutate(store = as_factor(as.character(store)))
ggplot(sample.data, aes(
x = store,
y = scaling,
color=version
)) +
geom_point(alpha = 0.7) +
theme(
axis.text.x = element_blank()
)
Upvotes: 0
Reputation: 206411
How about this
ggplot(sample.data, aes(
x = reorder(store, -scaling*(version=="benchmark"), max),
y = scaling,
color=version
)) +
geom_point(alpha = 0.7) +
theme(
axis.text.x = element_blank()
)
Here we multiply the non-benchmark scores by 0 (FALSE ~= 0) and take the max to reorder each group based only on the benchmark score.
Upvotes: 1