rregressiondata-fitting

In R, how to fit variables (A,B and C) in the same column such as A and B and also A and C in the same panel?


I have one dataset.

df=tibble::tibble(
   cultivar=rep(c("cv1", "cv2", "cv3"), each = 5L),
   treatment=rep(c("Control", "Type 1", "Type 2", "Type 3", "Type 4"), 3),
   weight=c(10.6475, 25.355, 34.455, 40.355, 49.4225, 11.33571, 26.47, 31.04, 34.59167,
    49.00857, 14.03, 32.5, 19.73, 47.705, 56.74),
    std_err = c(
    1.111796, 1.232541, 3.174625, 2.887711, 1.478566, 1.244666, 2.491744,
    4.798628, 5.259148, 4.009993, 0.62, 0.6, 1.34, 0.015, 2.32
  ),
)

df
   cultivar treatment  weight std_err
 1 cv1      Control      10.6   1.11 
 2 cv1      Type 1       25.4   1.23 
 3 cv1      Type 2       34.5   3.17 
 4 cv1      Type 3       40.4   2.89 
 5 cv1      Type 4       49.4   1.48 
 6 cv2      Control      11.3   1.24 
 7 cv2      Type 1       26.5   2.49 
 8 cv2      Type 2       31.0   4.80 
 9 cv2      Type 3       34.6   5.26 
10 cv2      Type 4       49.0   4.01 
11 cv3      Control      14.0   0.62 
12 cv3      Type 1       32.5   0.6  
13 cv3      Type 2       19.7   1.34 
14 cv3      Type 3       47.7   0.015
15 cv3      Type 4       56.7   2.32 

and I want to create a regression graph between cv1 and cv2, and also between cv1 and cv3. I want to place two regression lines in one panel. Also, I want to add standard errors in each data point.

In Excel, I can create a graph like the one below. I'm wondering how I can do that using R? I believe there are some codes available without transposing data.

Could you please let me know how to do it?

Always many thanks,

enter image description here


Solution

  • Here's a tidyverse solution based on joining your "cv1"s to the other cultivars:

    library(dplyr)
    library(ggplot2)
    
    plot_data <- left_join(
        filter(df, cultivar == "cv1"),
        filter(df, cultivar != "cv1"),
        join_by(treatment),
        suffix = c("", ".other")
      ) %>% 
      mutate(pair = paste0(cultivar, "-", cultivar.other))
    
    ggplot(plot_data, aes(weight, weight.other)) +
      geom_errorbar(
        aes(ymin = weight.other - std_err.other, ymax = weight.other + std_err.other),
        width = 1,
        linewidth = 0.2
      ) +
      geom_errorbarh(
        aes(xmin = weight - std_err, xmax = weight + std_err),
        height = 1,
        linewidth = 0.2
      ) +
      geom_point(aes(fill = pair), shape = 21, size = 3) +
      geom_smooth(aes(color = pair), method = lm, se = FALSE) +
      scale_color_manual(
        NULL, 
        values = c("midnightblue", "gold2"), 
        aesthetics = c("color", "fill")
      ) +
      coord_fixed() +
      labs(x = "cv 1", y = "cv 2 or cv 3") +
      theme_classic() +
      theme(
        text = element_text(family = "serif"),
        legend.position = "inside",
        legend.position.inside = c(.85, .1)
      )