1

I am trying to create a plot in ggplot2 showing the results of environmental sampling conducted over time. My data set has deployment and retrieval dates for samplers and the result of PCR on the end product. I want to make a graph with a line for each deployment so that he width is the duration (deploy to retrieve) and the vertical height is the Value.

      Deploy   Rertieve     Value
1 2021-08-29 2021-08-31  341.6431
2 2021-08-31 2021-09-02  259.8241
3 2021-09-02 2021-09-05  558.5531
4 2021-09-05 2021-09-07  872.5043
5 2021-09-07 2021-09-09 6130.8452
6 2021-09-10 2021-09-12 2655.0765

This is the code I used:

#Recreate the data frame above
sampling.dat <- structure(list(Deploy = structure(c(18868, 18870, 18872, 18875, 18877, 18880), class = "Date"), 
               Rertieve = structure(c(18870, 18872, 18875, 18877, 18879, 18882), class = "Date"), 
               Value = c(341.6431298, 259.824122, 558.5530897, 872.5042542, 6130.845229, 2655.076504)), 
          row.names = 1:6, class = "data.frame")

#Create the plot
Segment.plot <- ggplot(data = sampling.dat) +
  geom_segment(x="Deployment", y="Value", xend="Retrieve", yend="Value")
Segment.plot

When I run the code for the figure I get an error:

Error in `geom_segment()`:
! Problem while converting geom to grob.
ℹ Error occurred in the 1st layer.
Caused by error in `UseMethod()`:
! no applicable method for 'rescale' applied to an object of class "character"
Run `rlang::last_error()` to see where the error occurred.

None of the data used in the graph is in "character" class, all are either date or numeric.

This came from a larger file with lots of extra columns which I thought might be an issue. I created a new data frame (and a new .csv file) using just the relevant dates and numbers, but got the same errors.

  • 4
    Values from your data should be passed to ggplot in an `aes()` statement using symbols. You do not pass column names as strings with ggplot. It should look more like `geom_segment(aes(x=Deployment, y=Value, xend=Retrieve, yend=Value))`. This is a fundamental way ggplot works. If you are new to ggplot, maybe start off with some sort of introduction: https://ggplot2-book.org/introduction.html – MrFlick Jan 03 '23 at 21:07
  • That solved the issue thanks! I've used ggplot for a while, but never formally learned the structure so that link will be very helpful. – Seth Goodnight Jan 03 '23 at 21:41

1 Answers1

2
  1. Use aes(..) using symbols.
  2. Names do not match, perhaps typos in the question, but it's hard to know for sure.

Data, with updated names:

sampling.dat <- structure(list(Deployment = structure(c(18868, 18870, 18872, 18875, 18877, 18880), class = "Date"), Retrieve = structure(c(18870, 18872, 18875, 18877, 18879, 18882), class = "Date"), Value = c(341.6431298, 259.824122, 558.5530897, 872.5042542, 6130.845229, 2655.076504)), row.names = c(NA, 6L), class = "data.frame")

Code, fixed:

ggplot(data = sampling.dat) +
  geom_segment(aes(x=Deployment, y=Value, xend=Retrieve, yend=Value))

ggplot segment plot

If you need (or prefer) to use strings (i.e., programmatic use), then you can use the .data[[..]] method, described here:

ggplot(data = sampling.dat) +
  geom_segment(aes(x = .data[["Deployment"]], y = .data[["Value"]], 
                   xend = .data[["Retrieve"]], yend = .data[["Value"]]))

The strength of this is when you have variables defining which columns to use, as in col <- "Deployment" and then aes(x=.data[[col]], ...). (.data$Deployment also works, though defeats the notion of programmatic use.)

r2evans
  • 141,215
  • 6
  • 77
  • 149