0

I'm a total newbie to R. I'm trying to create a stacked bar chart based on this code:

activity <- c("mean_fairly_active", "mean_fairly_active", "mean_fairly_active",
              "mean_fairly_active", "mean_fairly_active", "mean_fairly_active",
              "mean_fairly_active", "mean_lightly_active", "mean_lightly_active",
              "mean_lightly_active", "mean_lightly_active", "mean_lightly_active",
              "mean_lightly_active", "mean_lightly_active", "mean_very_active",
              "mean_very_active", "mean_very_active", "mean_very_active",
              "mean_very_active", "mean_very_active", "mean_very_active",
              "mean_sedentary", "mean_sedentary", "mean_sedentary", 
              "mean_sedentary", "mean_sedentary", "mean_sedentary",
              "mean_sedentary")
minutes <- c("14.3", "13.1", "12.0", "12.1", "15.2", "14.5", "14.0", "197", "190",
             "185", "204", "207", "174", "192", "23.0", "20.8", "19.4", "20.1", 
             "21.9", "20.0", "23.1", "1007", "989", "962", "1000", "964", "990", 
             "1028")
weekday <- c("Sun", "Mon", "Tues", "Wed", "Thurs", "Fri", "Sat", "Sun", "Mon", 
             "Tues", "Wed", "Thurs", "Fri", "Sat", "Sun", "Mon", "Tues", "Wed",
             "Thurs", "Fri", "Sat", "Sun", "Mon", "Tues", "Wed", "Thurs", "Fri",
             "Sat")
merged_means <- data.frame (activity, minutes, weekday)
print(merged_means)

The ggplot I'm running:

ggplot(merged_means, aes(x=weekday, y=minutes, fill=activity)) +
  geom_bar(stat = "identity")

The resulting graph shows all the numbers of the y-axis squished on the bottom half of the graph, the days in the wrong chronological order (Fri, Mon, Sat, Sun, etc), and the fill colors in the wrong amounts. Any help is appreciated!

MrFlick
  • 195,160
  • 17
  • 277
  • 295
AndreaGH
  • 5
  • 4
  • You `minutes` are string rather than numeric values. Do you know how that happened? Try converting with something like `minutes <- as.numeric(minutes)`. Or fix whatever code changed them to strings in the first place. – MrFlick Jun 30 '22 at 21:12
  • I'm not sure...I typed them in by hand. I really appreciate this help, esp. since I'm so new at this!! – AndreaGH Jun 30 '22 at 21:17
  • Well, to save yourself some typing next time, you don't need quotes around numeric values. You would just have `minutes <- c(14.3, 13.1, 12.0, 12.1, ...)` for example. Plotting functions behave differently if you feed them numeric values vs character/strings values in quotes. – MrFlick Jun 30 '22 at 21:19

1 Answers1

4

You have a few issues to address:

  1. You need to convert minutes to numeric, since it is currently a character vector, and R doesn't know you intend these character strings to be interpreted as numbers.
  2. The weekdays are converted to a factor variable inside ggplot, and will therefore be arranged in alphabetical order. To prevent this, make weekday a factor variable with your chosen ordering.
  3. Writing geom_bar(stat = "identity") is just a long way of writing geom_col()
  4. For plotting purposes, it's a good idea to present your legend labels without distracting underscores, and to add appropriate axis titles.
  5. With clearly ordered factor levels like the activity scale, you should also make them a factor with the correct ordering.
  6. The default styling can be adjusted to taste, and in particular, it would be sensible for this data set to use a sequential palette to emphasise the activity level.

Putting all these together we might have something like this:

ggplot(merged_means, 
       aes(x    = factor(weekday, unique(weekday)), 
           y    = as.numeric(minutes), 
           fill = factor(trimws(gsub("mean|_", " ", activity)),
                         c("very active",
                           "fairly active",
                           "lightly active",
                           "sedentary")))) +
  geom_col(color = "gray50") +
  scale_fill_brewer(palette = "YlOrRd", direction = -1) +
  labs(x = "Weekday", y = "Minutes", fill = "Activity") +
  theme_minimal(base_size = 16)

enter image description here

Allan Cameron
  • 147,086
  • 7
  • 49
  • 87