0

It seems somewhat trivial to me, but I have the impression that my solution is somewhat... unnecessarily complicated. I would like to plot box plots and scatterplots side by side.
For example:

x <- rep(letters[1:2],5)
y <- 1:5
my_data <- data.frame(x, y, stringsAsFactors = FALSE)

require(ggplot2)
require(dplyr)

my_data_mod <- my_data %>% mutate(x_mod = if_else(x == 'a', 1.2, 2.2))
# I want to plot the points shifted by a certain value - 
# as x is 1,2 for the box plot (see below), 
# I assigned 1.2 and 2.2 for the scatter plots

p <- ggplot(data = my_data) + 
  geom_boxplot(aes(x, y), width = .1) + 
  geom_jitter(data = my_data_mod, aes(x_mod, y), width = .1)

p

enter image description here

Now, when I look at the underlying data frame of the box plot

str(ggplot_build(p)$data[[1]]$x)
num [1:2] 1 2

it obviously assigns numericals to x. So is there a simpler way to assign the 'shifted position' to my scatter plot? I tried

geom_jitter(aes(as.numeric(x) + 0.2, y)

but this throws a warning

Warning messages:
1: In FUN(X[[i]], ...) : NAs introduced by coercion
2: In min(x) : no non-missing arguments to min; returning Inf
3: In max(x) : no non-missing arguments to max; returning -Inf
4: Removed 10 rows containing missing values (geom_point).

Why???
As so often, thanks for your help and guidance.

tjebo
  • 21,977
  • 7
  • 58
  • 94
  • Thanks for pointing out to this question and your answer, which already suggested the 'factoring' suggested from AntoniosK. Hidden in this question is @DS_UNI 's comment and hint towards `position_nudge` which actually solves the problem very nicely too. Thanks @ everyone :) – tjebo May 18 '18 at 09:12
  • as pointed out by @AntoniosK below, position_nudge does indeed *not* help, as it does not allow for scatter. – tjebo May 18 '18 at 16:27

1 Answers1

2

This should work:

x <- rep(letters[1:2],5)
y <- 1:5
my_data <- data.frame(x, y, stringsAsFactors = FALSE)

require(ggplot2)
require(dplyr)

ggplot(data = my_data) + 
  geom_boxplot(aes(x, y), width = .1) + 
  geom_jitter(aes(as.numeric(as.factor(x)) + 0.2, y), width = .1)

enter image description here

AntoniosK
  • 15,991
  • 2
  • 19
  • 32
  • interesting. Thanks. I did not think of factorising. – tjebo May 18 '18 at 09:12
  • Again, as a double comment, because this might be overlooked easily: @DS_UNI has hinted towards `position = position_nudge()` which solves the problem maybe in the easiest way. – tjebo May 18 '18 at 09:18
  • 1
    @Tjebo I think the moment you use `position_nudge()` you fix the points at a specific `x` value. They don't have the random noise required. – AntoniosK May 18 '18 at 09:34
  • 1
    On my way - will check later . you might be right. – tjebo May 18 '18 at 09:38
  • Have a look and post it as a comment if you find a solution using `position_nudge()` or `position_jitter()` – AntoniosK May 18 '18 at 09:40