Home > front end >  In R ggplot, do a scatterplot with two different subsets
In R ggplot, do a scatterplot with two different subsets

Time:02-18

Here's what my data looks like. Long story short, I want to scatterplot Y values from Group A vs respective X values from Group B and optionally color it by Sample.

Here's what we're plotting

I do a lot of plotting of data like this (with many more variables), but it's always within a subset like subset(data, Group=='A') or subset(data, Group=='B'). This is the rare case when I need to plot across groups.

The plot code itself is simple:

ggplot(data, aes(x=X(B), y=Y(A), color=as.factor(Sample)))  
geom_point()

I realize that my X(B) and Y(A) won't work; that's just to illustrate the objective. I also assume there's a way to spit out a new dataset containing only the X(B) and Y(A) values; certainly open to any approach, but I prefer to work in GGPLOT for the actual graphs. Here's my dataset for reproducibility:

data <- structure(list(Group = c("A", "A", "A", "A", "A", "B", "B", "B", 
"B", "B", "A", "A", "A", "A", "A", "B", "B", "B", "B", "B"), 
    Sample = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), Point = c(1L, 2L, 3L, 4L, 
    5L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 
    5L), X = c(-3.26, -3.26, -3.26, -3.26, -3.26, -2.3624, -2.3877, 
    -2.6475, -3.0975, -3.1393, -3.26, -3.26, -3.26, -3.26, -3.26, 
    -0.6476, -0.7056, -0.7367, -0.9883, -0.9003), Y = c(22.55, 
    22.02, 19.41, 10.92, 8.3, 4.14, 4.42, 9.92, 9.86, 7.57, 67.94, 
    66.92, 70.26, 63.37, 61.85, 11.79, 10.86, 12.96, 12.44, 11.69
    )), class = "data.frame", row.names = c(NA, -20L))

CodePudding user response:

You can get the equivalent of X(B) and Y(A) by pivoting:

library(tidyverse)

pivoted <- data %>% 
  pivot_wider(names_from = Group, values_from = X:Y)

# data before pivoting
head(as_tibble(data))

# # A tibble: 6 x 5
#   Group Sample Point     X     Y
#   <chr>  <int> <int> <dbl> <dbl>
# 1 A          1     1 -3.26 22.6 
# 2 A          1     2 -3.26 22.0 
# 3 A          1     3 -3.26 19.4 
# 4 A          1     4 -3.26 10.9 
# 5 A          1     5 -3.26  8.3 
# 6 B          1     1 -2.36  4.14

# after pivoting
head(pivoted)

# # A tibble: 6 x 6
#   Sample Point   X_A    X_B   Y_A   Y_B
#    <int> <int> <dbl>  <dbl> <dbl> <dbl>
# 1      1     1 -3.26 -2.36   22.6  4.14
# 2      1     2 -3.26 -2.39   22.0  4.42
# 3      1     3 -3.26 -2.65   19.4  9.92
# 4      1     4 -3.26 -3.10   10.9  9.86
# 5      1     5 -3.26 -3.14    8.3  7.57
# 6      2     1 -3.26 -0.648  67.9 11.8 

Then you can easily adapt your illustration code:

ggplot(pivoted, aes(x=X_B, y=Y_A, color=as.factor(Sample)))  
  geom_point()

CodePudding user response:

You can rearrange the data frame using filter, select and bind_cols.

library(dplyr)
library(ggplot2)

data %>% 
  filter(Group == "A") %>% 
  select(Sample, Y) %>% 
  bind_cols(data %>% 
              filter(Group == "B") %>% 
              select(X))

Result:

   Sample     Y       X
1       1 22.55 -2.3624
2       1 22.02 -2.3877
3       1 19.41 -2.6475
4       1 10.92 -3.0975
5       1  8.30 -3.1393
6       2 67.94 -0.6476
7       2 66.92 -0.7056
8       2 70.26 -0.7367
9       2 63.37 -0.9883
10      2 61.85 -0.9003

Then pipe that to ggplot:

data %>% 
  filter(Group == "A") %>% 
  select(Sample, Y) %>% 
  bind_cols(data %>% 
              filter(Group == "B") %>% 
              select(X)) %>% 
ggplot(aes(X, Y))   
geom_point(aes(color = factor(Sample)))

Result:

enter image description here

CodePudding user response:

Here's another way to reshape your data. We pivot longer to get the X and Y values on their own row, and then we can filter to keep just the Y values from A and the X values from B. Then we can reshape again to have just one row with an X and Y value for each Sample/Point compbination.

library(dplyr)
library(tidyr)
library(ggplot)

data %>% 
  pivot_longer(cols=c(X,Y)) %>% 
  filter((Group=="A" & name=="Y") | (Group=="B" & name=="X")) %>% 
  pivot_wider(id=c(Sample, Point), names_from = name, values_from = value) %>%
  ggplot()    
    aes(X,Y, color=as.factor(Sample))   
    geom_point()

The main point is that you need to get your data in the right order before you try plotting it. ggplot always assumes you have "tidy" data. Try to avoid doing weird data manipulations when trying to plot.

  • Related