helloiambrain
helloiambrain

Reputation: 19

Error in FUN(X[[i]], ...) : object not found in ggplot

I got an error for the code below which I could not understand: Error in FUN(X[[i]], ...) : object 'avg_Depression' not found What could be the reason?

 data %>%
      group_by(Group, Time) %>%
      dplyr::summarise(avg_Depression = mean(Depression),
                      se_Depression = sd(Depression)/sqrt(n())) %>%
      ggplot(data = data, 
           mapping = aes(x = Rumination, 
                         y = Depression,
                         color = Time,
                         ymin = avg_Depression - se_Depression,
                         ymax = avg_Depression + se_Depression)) +
                         geom_pointrange(size = 1.2, alpha = .6, 
                         position = position_dodge(width = .1)) +
           geom_smooth(formula = y ~ x, method = lm, se=F)+
           facet_wrap(~Group)+
           theme_bw() +
           theme(panel.grid.major = element_blank(),
                 panel.grid.minor = element_blank())

Upvotes: 1

Views: 7140

Answers (1)

r2evans
r2evans

Reputation: 160687

stefan's note is exactly right.

When you start, data represents your data in a named object. As soon as R executes through %>% group_by(...), the values and structure of the object is ephemeral, not existing in a named object. Just like in a <- 5 ; a + 9, the 14 is never assigned to anything. This is often either later explicitly stored into a new object

newdata <- data %>%
  group_by(...) %>%
  summarize(...)
## or less-commonly-seen right-hand assignment
data %>%
  group_by(...) %>%
  summarize(...) -> newdata

or discarded, solely for the side-effect, as you are intending to do here:

data %>%
  group_by(...) %>%
  summarize(...) %>%
  ggplot(...) + geom_point() + ...

In your case, you group and then summarize the data, adding avg_Depression, and then assign data=data referring to the original contents of the object named data. There are two problems with this:

  1. Your new summarized data is not included here. In fact, ggplot(.) does not see summarized data, it sees the raw data.

  2. You don't explicitly assign where the piped data is going. Often you may see people code in the . placeholder for explicit/self-documenting %>%-pipe-flow, such as

    mylm <- mydata %>%
      group_by(...) %>%
      summarize(...) %>%
      lm(A ~ B + C, data = .)
    

    By default, the %>% pipe operator will place the data from the previous step (LHS) into the first argument of the next step (RHS). However, if the RHS expression includes the . placeholder, then the data is assigned to that argument instead. (This does not work the same as the native-R |> pipe, btw, not a factor here.)

    Because you do not include the explicit . placeholder, though, this is what is actually happening:

     data %>%
          group_by(Group, Time) %>%
          dplyr::summarise(avg_Depression = mean(Depression),
                          se_Depression = sd(Depression)/sqrt(n())) %>%
          ggplot(., data = data, 
               mapping = aes(...)) + ...
    

    which means that the piped data is falling with ggplot's ... (catch-all) argument. You don't hear about this because from ?ggplot2::ggplot:

     ```
     Arguments:
         data: Default dataset to use for plot. If not already a data.frame,
               will be converted to one by 'fortify()'. If not specified,
               must be supplied in each layer added to the plot.
      mapping: Default list of aesthetic mappings to use for plot. If not
               specified, must be supplied in each layer added to the plot.
          ...: Other arguments passed on to methods. Not currently used.
     ```
    

    the ... is not currently used.

Bottom line, change your data=data to data=. (or just remove data=data completely), and it should work:

 data %>%
      group_by(Group, Time) %>%
      dplyr::summarise(avg_Depression = mean(Depression),
                      se_Depression = sd(Depression)/sqrt(n())) %>%
      ggplot(data = .,                                               # change here 
           mapping = aes(x = Rumination, 
                         y = Depression,
                         color = Time,
                         ymin = avg_Depression - se_Depression,
                         ymax = avg_Depression + se_Depression)) +
                         geom_pointrange(size = 1.2, alpha = .6, 
                         position = position_dodge(width = .1)) +
           geom_smooth(formula = y ~ x, method = lm, se=F)+
           facet_wrap(~Group)+
           theme_bw() +
           theme(panel.grid.major = element_blank(),
                 panel.grid.minor = element_blank())

Upvotes: 1

Related Questions