GGPlot for activity minutes over weekdays

Hi! I wanted to share a big thanks for helping me. I was able to change the column names and move forward. I am hoping you can help me a little more.

  1. I really want to plot something that shows the different levels of activity distance (given the total) across each of the weekdays. Ultimately Im wanting to look at the amount of light, moderate and very active minutes each weekday. This is a given but each equal the TotalDistance column.

  2. Im wanting to have plots that show the level of intensity vs amount of calories (assuming there is a positive reln there) but then to cross referencing those levels across each weekday. Are ppl doing higher intensity workouts on given days of the week? My thought is that should align with seeing a higher number of calories burned on those days too.

Data is taken from dailymerged df.

dput(head(dailymerged,3))
structure(list(Id = c(1503960366, 1503960366, 1503960366), Date = structure(c(16903, 
16904, 16906), class = "Date"), Weekday = structure(c(3L, 4L, 
6L), .Label = c("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
), class = c("ordered", "factor")), Calories = c(1985L, 1797L, 
1745L), TotalSteps = c(13162L, 10735L, 9762L), TotalDistance = c(8.5, 
6.96999979019165, 6.28000020980835), VeryActiveDistance = c(1.87999999523163, 
1.57000005245209, 2.14000010490417), ModeratelyActiveDistance = c(0.550000011920929, 
0.689999997615814, 1.25999999046326), LightActiveDistance = c(6.05999994277954, 
4.71000003814697, 2.82999992370605), SedentaryActiveDistance = c(0, 
0, 0), VeryActiveMinutes = c(25L, 21L, 29L), FairlyActiveMinutes = c(13L, 
19L, 34L), LightlyActiveMinutes = c(328L, 217L, 209L), SedentaryMinutes = c(728L, 
776L, 726L), TotalSleepRecords = c(1L, 2L, 1L), TotalMinutesAsleep = c(327L, 
384L, 412L), TotalTimeInBed = c(346L, 407L, 442L)), row.names = c(NA, 
3L), class = "data.frame")

I did this so far but its not really giving me what I am looking for.

ggplot(dailymerged, aes(x= Weekday, y= c("LightlyActiveDistance"), color= Weekday))+
  geom_col()

ggplot(dailymerged, aes(x= Weekday, y= c("ModeratelyActiveDistance"), color= Weekday))+
  geom_col()

ggplot(dailymerged, aes(x= Weekday, y= c("VeryActiveDistance"), color= Weekday))+
  geom_col()

How can I change this to get the effects that Im looking for. I know there has to be a simple way and Im aware of facet_wrap but not sure exactly how to use it for what Im trying to achieve.
Thanks,
Kathryn

I think the key to getting what you want in item 1 is to reshape the data. I had to slightly rename some columns so that the reshaping would produce a neat result. Take a look at the data frame after each step and see if it makes sense. In the end, I make two plot, one stacked and the other with side-by-side columns.
It is not clear to me how to get at what you want in item 2. I'll post again if I find something good.

library(tidyverse)
#> Warning: package 'tibble' was built under R version 4.1.2
dailymerged <- structure(list(Id = c(1503960366, 1503960366, 1503960366), 
                              Date = structure(c(16903, 16904, 16906), class = "Date"), 
                              Weekday = structure(c(3L, 4L,6L), .Label = c("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"), class = c("ordered", "factor")), 
                              Calories = c(1985L, 1797L, 1745L), 
                              TotalSteps = c(13162L, 10735L, 9762L), 
                              TotalDistance = c(8.5, 6.96999979019165, 6.28000020980835), 
                              VeryActiveDistance = c(1.87999999523163, 1.57000005245209, 2.14000010490417), 
                              ModeratelyActiveDistance = c(0.550000011920929, 0.689999997615814, 1.25999999046326), 
                              LightActiveDistance = c(6.05999994277954, 4.71000003814697, 2.82999992370605), 
                              SedentaryActiveDistance = c(0, 0, 0), 
                              VeryActiveMinutes = c(25L, 21L, 29L), 
                              FairlyActiveMinutes = c(13L, 19L, 34L), 
                              LightlyActiveMinutes = c(328L, 217L, 209L), 
                              SedentaryMinutes = c(728L, 776L, 726L), 
                              TotalSleepRecords = c(1L, 2L, 1L), 
                              TotalMinutesAsleep = c(327L, 384L, 412L), 
                              TotalTimeInBed = c(346L, 407L, 442L)), 
                         row.names = c(NA, 3L), class = "data.frame")

dailymerged <- dailymerged |> 
  rename(LightlyActiveDistance=LightActiveDistance,
         ModeratelyActiveMinutes=FairlyActiveMinutes,
         SedentaryDistance=SedentaryActiveDistance)

ActivityLong <- dailymerged |> 
  pivot_longer(VeryActiveDistance:SedentaryMinutes, names_to = "Level_Metric")

#Show the new data in two steps for better display
ActivityLong <- ActivityLong |> 
  mutate (Level = str_remove(Level_Metric, "Distance|Minutes"),
          Metric = str_extract(Level_Metric, "Distance|Minutes")) |> 
  select(-Level_Metric)

ActivityLong <- ActivityLong |> 
  pivot_wider(names_from = "Metric", values_from = "value")
ActivityLong <- ActivityLong |> 
  mutate(Level=factor(Level,levels = c("Sedentary","LightlyActive",
                                       "ModeratelyActive","VeryActive")))

ggplot(ActivityLong, aes(Weekday,y = Minutes,fill=Level)) + 
  geom_col()

ggplot(ActivityLong, aes(Weekday,y = Minutes,fill=Level)) + 
  geom_col(position="dodge")

Created on 2022-05-21 by the reprex package (v2.0.1)

Hi! Thank you for showing me this. I was able to see what you did with the names with a new dataframe. So, I tried to take it one step further and evaluate sleep but kept getting errors. I was trying to see there is any patterns of sleep that come up based on day of the week and either calories burned or level of activity. Like are people are that are burning more calories sleeping longer or shorter. Or do people sleep longer on certain days of the week? Ill try to play around a little more and see if I can figure it out, but could use your help.

This is what I was getting:

 ggplot(ActivityLong, aes(x= Weekday, y= TotalMinutesAsleep, fill=Level))
>   geom_col(position_stack)
Error in `validate_mapping()`:
! `mapping` must be created by `aes()`
Run `rlang::last_error()` to see where the error occurred.
> ggplot(ActivityLong, aes(x= Weekday, y= TotalMinutesAsleep, fill=Level))
>   geom_col(position= "stack")
geom_col: width = NULL, na.rm = FALSE
stat_identity: na.rm = FALSE
position_stack 

It looks like you are running geom_col() separately from ggplot(). You need to connect the two with a + sign.

ggplot(ActivityLong, aes(x= Weekday, y= TotalMinutesAsleep, fill=Level)) + geom_col(position = "stack")

Thank you! I also tried this but when I run it I cant get a smooth line, do you know why?

ggplot(ActivityLong, aes(x = Weekday, y = TotalMinutesAsleep,)) + 
  geom_point()+
  geom_smooth()

This is the error I keep getting:
ggplot(ActivityLong, aes(x = Weekday, y = TotalMinutesAsleep,)) +

  • geom_point()+
  • geom_smooth()
    geom_smooth() using method = 'loess' and formula 'y ~ x'

So, then I ran it like this:

ggplot(ActivityLong, aes(x = Weekday, y = TotalMinutesAsleep,)) + 
+   geom_point()+
+   geom_smooth(formula = y ~ x, method = "lm")

but after that I dont get a smooth line. Not sure what else to do.

It seems geom_smooth will not calculate a line if the x values are a factor and Weekday is a factor. It is fairly easy to work around that limitation in this case. Note that I am plotting the data frame dailymerged from which ActivityLong was built. It contains the three values of Weekday and TotalMinutesAsleep in individual columns so they are convenient for plotting. In ActivityLong, the Weekday and TotalMinutesAsleep numbers are repeated many times, which is not an accurate representation of your data.
To get geom_smooth to plot, I used as.numeric(Weekday) to extract the numeric value of the factor. I included an offset of - 2 as an inaccurate hack to make the plot look approximately correct. You can see why from this code.

as.numeric(dailymerged$Weekday)
[1] 3 4 6

Your three days of Tuesday, Wednesday, and Friday have numeric values of 3,4,6, since Sunday = 1. On the plot those three factor values are placed in the positions 1, 2, and 3. By subtracting two, I get the first two to line up correctly and you can see the general idea of the plot. If your real data have all the days of the week, you will not have to worry about any offset.

library(tidyverse)
#> Warning: package 'tibble' was built under R version 4.1.2
dailymerged <- structure(list(Id = c(1503960366, 1503960366, 1503960366), 
                              Date = structure(c(16903, 16904, 16906), class = "Date"), 
                              Weekday = structure(c(3L, 4L,6L), .Label = c("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"), class = c("ordered", "factor")), 
                              Calories = c(1985L, 1797L, 1745L), 
                              TotalSteps = c(13162L, 10735L, 9762L), 
                              TotalDistance = c(8.5, 6.96999979019165, 6.28000020980835), 
                              VeryActiveDistance = c(1.87999999523163, 1.57000005245209, 2.14000010490417), 
                              ModeratelyActiveDistance = c(0.550000011920929, 0.689999997615814, 1.25999999046326), 
                              LightActiveDistance = c(6.05999994277954, 4.71000003814697, 2.82999992370605), 
                              SedentaryActiveDistance = c(0, 0, 0), 
                              VeryActiveMinutes = c(25L, 21L, 29L), 
                              FairlyActiveMinutes = c(13L, 19L, 34L), 
                              LightlyActiveMinutes = c(328L, 217L, 209L), 
                              SedentaryMinutes = c(728L, 776L, 726L), 
                              TotalSleepRecords = c(1L, 2L, 1L), 
                              TotalMinutesAsleep = c(327L, 384L, 412L), 
                              TotalTimeInBed = c(346L, 407L, 442L)), 
                         row.names = c(NA, 3L), class = "data.frame")


ggplot(dailymerged, aes(x = Weekday, y = TotalMinutesAsleep,)) + 
     geom_point()+
     geom_smooth(formula = y ~ x, method = "lm",aes( x = as.numeric(Weekday)-2))

Created on 2022-05-23 by the reprex package (v2.0.1)

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.