This example pulls visits by device type by hour for the last 30 days and then plots the data as a heatmap. In this example, we simply use ggplot functionality. Another approach is to use the highcharter package as described in this example.

We’re actually going to plot the average visits by hour-weekday rather than the total. Otherwise, we’d be stacking the deck for a couple of weekdays by pulling 30 days rather than a divisible-by-7 number of days.


Be sure you’ve completed the steps on the Initial Setup page before running this code.

For the setup, we’re going to load a few libraries, load our specific Adobe Analytics credentials, and then authorize with Adobe.

# Load the necessary libraries. The 'typical' way to do this is with a series of
# 'library([library name])' calls. The use of the pacman package, though, adds a
# check that will install any missing packages before then loading them.
if (!require("pacman")) install.packages("pacman")
               jsonlite)    # Needed for unbox() in examples with inline segments

# Load the username, shared secret, and report suite ID
username <- Sys.getenv("ADOBE_API_USERNAME")
secret <- Sys.getenv("ADOBE_API_SECRET")

# Authorize Adobe Aalytics.
SCAuth(username, secret)

# Set the RSID and the date range. If you want to, you can swap out the Sys.getenv()
# call and just replace that with a hardcoded value for the RSID. And, the start 
# and end date are currently set to choose the last 30 days, but those can be 
# hardcoded as well.
rsid <- Sys.getenv("ADOBE_RSID")
start_date <- Sys.Date() - 31        # 30 days back from yesterday
end_date <- Sys.Date() - 1           # Yesterday

If that all runs with just some messages but no errors, then you’re set for the next chunk of code: pulling the data.

Pull the Data

This is a fairly simple query. We’re going to need both the date (to determine day of week) and the hour of the day. When we specify a date.granularity of hour, we actually get both a datetime column and an hour column returned, which actually simplifies our data munging a bit.

For giggles, we’re also going to pull the data broken out by device type so that we can do a little extra visualization. This means we’ll first have to roll up the data to remove the device type for our initial visualization, but that’s a simple enough step.

# Pull the data. See ?QueueTrended() for additional parameters.
aa_data <- QueueTrended(rsid,
                        date.from = start_date,
               = end_date,
                        metrics = "visits",
                        elements = "mobiledevicetype",
                        date.granularity = "hour")
# Go ahead and do a quick inspection of the data that was returned. This isn't required,
# but it's a good check along the way.
datetime hour name url visits
2018-02-17 00:00:00 0 Other 3
2018-02-17 00:00:00 0 Mobile Phone 3
2018-02-17 00:00:00 0 Tablet 0
2018-02-17 01:00:00 1 Other 2
2018-02-17 01:00:00 1 Mobile Phone 4
2018-02-17 01:00:00 1 Tablet 0

Data Munging

We need to do a few things in this step:

# Convert the datetime from POSIXlt to Date. This makes the next step smoother.
aa_data$datetime <- as.Date(aa_data$datetime)

# Add a column with the weekday and then abbreviate the weekday to be just
# the first 3 letters. Then, make that column a factor with the 
# values in a specific order (the normal order for days of the week)
aa_data <- aa_data %>% 
  mutate(weekday = weekdays(datetime)) %>% 
  mutate(weekday = factor(weekday,
                          levels =  c("Sunday", "Monday", "Tuesday", "Wednesday",
                                      "Thursday", "Friday", "Saturday")))

# Clean up the table a bit by convering "Other" to "Desktop/Tablet" and
# then grabbing just the columns of interest.
aa_data <- aa_data %>% 
  mutate(Device = ifelse(name=="Other", "Desktop/Tablet", name)) %>% 
  select(datetime, weekday, hour, Device, visits) 

# Check what it looks like now
datetime weekday hour Device visits
2018-02-17 Saturday 0 Desktop/Tablet 3
2018-02-17 Saturday 0 Mobile Phone 3
2018-02-17 Saturday 0 Tablet 0
2018-02-17 Saturday 1 Desktop/Tablet 2
2018-02-17 Saturday 1 Mobile Phone 4
2018-02-17 Saturday 1 Tablet 0

Now, we’re going to make two sets of data from aa_data:

# Group by the weekday, hour, and devicetype, and then summarise by getting the
# mean of the visits.
aa_data_devicetype <- aa_data %>% 
  group_by(weekday, hour, Device) %>% 
  summarise(visits = mean(visits))

# Do the same thing, but leave out devicetype
aa_data_totals <- aa_data %>% 
  group_by(weekday, hour) %>% 
  summarise(visits = mean(visits))

# Check what the second one looks like
weekday hour visits
Sunday 0 1.0666667
Sunday 1 0.6666667
Sunday 2 0.5333333
Sunday 3 0.3333333
Sunday 4 0.4666667
Sunday 5 0.4666667

Data Visualization

This won’t be the prettiest possible plot, but we’ll do a bit of tweaking to make it “better than the defaults.”" If you want to read up more on ggplot, this page on is worth checking out.

# Create a theme that is a bit more friendly. This isn't required to do the visualization,
# but it's a painful heatmap to look at otherwise. We start with a minimalist theme... and
# then basically make it even more minimalist. Thank you, Tufte and Few.
theme_heatmap <- theme_light() +                 # Start with a minimalist theme
  theme(panel.grid = element_blank(),            # Remove the gridlines
        panel.border = element_blank(),          # Remove the border around the heatmap
        plot.title = element_text(face = "bold", # Make the title bold
                                  size = 11,     # Adjust the title size
                                  hjust = 0.5),  # Center the title
        axis.ticks = element_blank(),            # Remove the axis tickmarks
        axis.title.x = element_blank(),          # Turn off the x-axis title 
        axis.title.y = element_text(size=10),    # Adjust the size of the y-axis title
        axis.text.y = element_text(size = 8),    # Adjust the size of the y-axis labels
        axis.text.x = element_text(size = 10),   # Adjust the size of the x-axis labels
        legend.position = "none")                # Turn off the legend

# Create the plot.
gg <- ggplot(aa_data_totals, mapping = aes(x = weekday, y = hour, 
                                           fill = visits)) +
  geom_tile(colour="white") +  # This makes the heatmap (the colour is the lines in the grid)
  scale_fill_gradient(low = "#f4fff6", high="#0bb730") +  # The colour range to use
  scale_y_reverse(breaks=c(23:0), labels=c(23:0),    # Put the 0 at the top of the y-axis
                  expand = c(0,0)) +                 # Remove padding around the heatmap
  scale_x_discrete(expand = c(0,0), position = "top") +
  labs(title = "Average Visits by Day of Week / Hour of Day", y = "Hour of Day") +
  theme_heatmap  # Apply the theme defined earlier for styling

# Output the plot. You *could* just remove the "gg <-" in the code above, but it's
# generally a best practice to create a plot object and then output it, rather than
# outputting it on the fly.

If we wanted to see the actual average visits within the cells, we can take the plot object (gg) we created already and just extend it a little bit by adding geom_text() to it.

# Make a new plot object that adds text in the cells
gg_labeled <- gg +
  geom_text(aes(label = sprintf("%.1f", visits)),  # sprintf formats to 2 decimals
            size = 3)                              # And we need to tweak the font size

# Output that object

Alternatively, we can quickly make three heatmaps as “facets” – one for each device type. We’ll use the aa_data_devicetype for this, but, other than adding a facet_grid component, it’s pretty much the same as the original heatmap (and we can use the theme we already defined). Notice how the shading is based on all of the plots. Since there is very little traffic from tablets, there is no real “peak” time relative to all traffic.

# Create the plot.
gg_devicetype <- ggplot(aa_data_devicetype, mapping = aes(x = weekday, y = hour, 
                                                          fill = visits)) +
  geom_tile(colour="white") +  
  scale_fill_gradient(low = "#f4fff6", high="#0bb730") + 
  scale_y_reverse(breaks=c(23:0), labels=c(23:0),
                  expand = c(0,0)) +
  scale_x_discrete(expand = c(0,0), position = "top") +
  labs(title = "Average Visits by Day of Week / Hour of Day", y = "Hour of Day") +
  facet_grid(Device ~ .) +    # This is the sole addition to the plot

# Output the plot.

This site is a sub-site to