8

I am trying to compare values in condition x vs y. Here is my data:

mydata <-  structure(list(
  Row.names = c("ASPTAm", "ATPtmB_MitoCore", "CI_MitoCore", 
                "CIII_MitoCore", "CIV_MitoCore", "CO2t", "CO2tm", "CV_MitoCore", 
                "H2Ot", "H2Otm", "MDH", "MDHm", "O2t", "O2tm", "OF_ATP_MitoCore", 
                "PGK", "PGM", "PIt2mB_MitoCore", "SUCOASm"), 
  mean_x = c(-1.416333333, 
             26.1376024, 8.444222444, 9.983111555, 4.991555778, -5.06, -5.055, 
             24.43926907, -4.719, -30.9051024, -1.580333333, 3.093666667, 
             5, 5, 29.7476024, -1.81, -1.81, 25.9436024, -1.698333333), 
  mean_y = c(-2.455e-14, 
             78.68825722, 51.30062794, 9.897398744, 4.948699372, -40.05114286, 
             -40.15114286, 68.14247151, -29.51685714, -108.3586144, -60.164, 
             10.90278571, 5, 5, 82.39825722, -1.81, -1.81, 86.41154294, -10.58878571
  )), 
  class = "data.frame", row.names = c(NA, -19L), 
  .Names = c("Row.names", "mean_x", "mean_y"))

I want a point graph with a line connecting between each group. Here is what I tried:

library(reshape2)
library(ggplot2)

mydata <- melt(mydata)

ggplot(mydata, aes(x = Row.names, y = value, color = variable)) +
  geom_point(stat = 'identity', position = position_dodge(width = 1.0), size = 2.5) +
  theme(axis.text.x = element_text(angle = 60, hjust = 1)) 

This is the plot I get:

img from link 1

I also want to connect the two points in each variable.
If I group the data by Row.names and then add geom_line(), it works but the points in each group overlap again.

img form link 2

How do I separate the points while connecting them?

Z.Lin
  • 28,055
  • 6
  • 54
  • 94
Prashant
  • 95
  • 7
  • Use `group = variable` within `aes` if you want to connect points per `variable`, if you want one line use `group = 1`. Also, you have to add `+ geom_line` (`geom_line(color = "black")` if you want only one line). – pogibas Jan 17 '19 at 06:49
  • 2
    @PoGibas I don't think that is OPs problem. @Prashant, do you want to connect the dots for the unique `Row.names` but keep the `position_dodge()`? – LAP Jan 17 '19 at 06:54
  • 2
    @PoGibas I want the line to be connected in a way showed [here](https://imgur.com/a/OqIaKca) while shifting points of variable.y slightly so they don't overlap. – Prashant Jan 17 '19 at 06:56
  • @LAP yes exactly. – Prashant Jan 17 '19 at 06:57
  • 1
    This might help: [Combining geom_point and geom_line with poisition_jitterdodge in ggplot2 for two grouping factors](https://stackoverflow.com/questions/37020435/combining-geom-point-and-geom-line-with-position-jitterdodge-in-ggplot2-for-two) – LAP Jan 17 '19 at 07:06
  • @LAP In the above example, there seems to be no grouping to connect the points and the jittering is manual. I must be missing something. Can you explain me in the answer below? – Prashant Jan 17 '19 at 07:35
  • To be honest, I only glanced through the thread. I'm sorry for wasting your time if it was not relevant at all. – LAP Jan 17 '19 at 07:37
  • 1
    @Prashant The second answer in the question linked by @LAP should address your use case? Something like `ggplot(mydata, aes(x = as.numeric(interaction(variable, Row.names)), y = value, color = variable, group = Row.names)) + geom_point() + geom_line() + scale_x_continuous(breaks = seq(1.5, nrow(mydata) - 0.5, 2), labels = sort(unique(mydata$Row.names))) + theme(axis.text.x = element_text(angle = 60, hjust = 1), panel.grid.minor.x = element_blank())` – Z.Lin Jan 17 '19 at 08:55

1 Answers1

2

One way you can achive this is by using %.>% pipe from wrapr package and reshaping data specifically to the geom_*().

library(tidyverse)
library(wrapr)

mydata %>%
  mutate(
    x = row_number(),
    more = mean_x < mean_y,
    x1 = if_else(more, x - .1, x + .1),
    x2 = if_else(more, x + .1, x - .1)
  ) %.>%
  ggplot() +
  geom_segment(
    data = .,
    aes(
      x = x1,
      xend = x2,
      y = mean_x,
      yend = mean_y
    ),
    color = 'grey'
  ) +
  geom_point(
    data = unite(., 'mean_x', c('mean_x', 'x1')) %>%
      unite('mean_y', c('mean_y', 'x2')) %>%
      gather(variable, value, mean_x:mean_y) %>%
      separate(value, c('y', 'x'), sep = '_') %>%
      mutate_at(4:5, as.numeric),
    aes(
      x = x,
      y = y,
      color = variable
    )
  ) +
  ylab('value') +
  xlab('Row.names') +
  scale_x_continuous(
    breaks = .$x,
    labels = .$Row.names
  ) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 60, hjust = 1))

enter image description here

Paweł Chabros
  • 2,349
  • 1
  • 9
  • 12