如何跟踪博客的性能?

Antoine Soetewey 2020-12-16 99 minute read

介绍

统计和r 已于2019年12月16日推出。由于博客今天正式一岁,讨论了主要 维护技术博客的好处,我以为是分享一些数字和想法的好时机。

在本文中,我展示了如何 分析博客及其博客帖子 with the {googleAnalyticsR} R package (see package’s 完整的文件)。在分享关于博客的一些分析之后,我还将讨论内容创建/分发,并在更小的程度上讨论未来的计划。这是一种分享我作为数据科学博主的旅程的方式,以及一种让您了解统计数据和r如何做的方式。

I decided to share with you some numbers through the {googleAnalyticsR} package instead of the regular Google Analytics dashboards for several reasons:

  1. 有大量的数据分析师在通过他们的专用平台分析Google Analytics数据时,这些分析师比我更加经验
  2. I recently discovered the {googleAnalyticsR} package in R and I would like to present its possibilities, and perhaps convince marketing specialists familiar with R to complement their Google Analytics dashboards with some data visualizations made in R (via some ggplot2可视化 for instance)
  3. 我想要 自动化过程 这样我很容易的方式 复制 多年来的分析相同。这将允许查看博客在整个年内如何发展。我们知道,在自动化和复制方面,使用R是一个非常好的起点 - 特别感谢 r markdown.报告

我不是领域的专家 数字营销但是,谁知道,它仍然可以向数据分析师,SEO专家或其他博主使用R.使用R.使用R.追踪自己的博客或网站的表演的一些想法。对于那些对更浓缩的分析感兴趣的人,看看我的 自定义Google Analytics仪表板.1

在进一步前进之前,我想提醒我并没有从我的博客中谋生(远离它!),绝对不是我的目标,因为我不相信如果是我的话,我会是同一种作家主要职业。

先决条件

As for any package in R, we first need to install it—with install.packages()—and load it—with library():2

# install.packages('googleAnalyticsR', dependencies = TRUE)
library(googleAnalyticsR)

Next, we need to authorize the access of the Google Analytics account using the ga_auth() function:

ga_auth()

运行此代码将打开一个浏览器窗口,您将能够授权访问权限。此步骤将保存授权令牌,因此您只需要这样做一次。

Make sure to run the ga_auth() function in a R script and not in a r markdown. 文档。跟随这一点 程序 如果要在R MARKDOWN报告中使用该软件包及其函数,或者在像本文所做的那样的博客文章中。

Once we have completed the Google Analytics authorization, we will need the ID of the Google Analytics account we want to access. All the available accounts linked to your email address (after authentication) are stored in ga_account_list():

accounts <- ga_account_list()

accounts
## # A tibble: 2 x 11
##   accountId accountName internalWebProp… level websiteUrl type  starred
##   <chr>     <chr>       <chr>            <chr> <chr>      <chr> <lgl>  
## 1 86997981  Antoine So… 129397861        STAN… //w… WEB   NA     
## 2 86997981  Antoine So… 218214896        STAN… //s… WEB   TRUE   
## # … with 4 more variables: webPropertyId <chr>, webPropertyName <chr>,
## #   viewId <chr>, viewName <chr>
accounts$webPropertyName
## [1] "Antoine Soetewey" "statsandr.com"

正如您所看到的,我有两个链接到我的Google Analytics配置文件的帐户:一个用于我个人网站的一个帐户(www.antoinesoetewey.com.)和这个博客。

当然,我选择链接到此博客的帐户:

# select the view ID by property name
view_id <- accounts$viewId[which(accounts$webPropertyName == "statsandr.com")]

确保使用自己的属性名称编辑代码。

我们现在终于准备好在R中使用我们的Google Analytics数据进行更好的分析!

分析

用户,页面浏览和会话

让我们从一些一般数字开始,例如数量 用户,会话和页面浏览量 对于整个网站。请注意,对于本文,我们在过去一年中使用数据,因此2019年12月16日至2020年12月15日:

# set date range
start_date <- as.Date("2019-12-16")
end_date <- as.Date("2020-12-15")

# get Google Analytics (GA) data
gadata <- google_analytics(view_id,
  date_range = c(start_date, end_date),
  metrics = c("users", "sessions", "pageviews"),
  anti_sample = TRUE # slows down the request but ensures data isn't sampled
)
gadata
##    users sessions pageviews
## 1 321940   428217    560491

在它的第一年,统计数据和r已被吸引 321,940个用户,谁产生了总共 428,217次会议560,491次浏览量.

对于那些不熟悉Google Analytics数据的人和这些指标之间的区别,请记住:

  • a 用户 是在一段时间内访问您网站的新人和返回的人数
  • a 会议 是一组用户与您的网站进行交互,在给定的时间范围内进行
  • a 页面预览,正如名称所示,被定义为您网站上的页面的视图

因此,如果人们读取三个博客帖子,那么离开网站和人员B阅读一个博客帖子,您的关于页面然后离开网站,Google Analytics数据将显示2个用户,2个会话和5页视图。

会话随着时间的推移

除了上面呈现的相当一般指标之外,还有有趣的是说明每天的会话数量 随着时间的推移 在一个 散点图 - 用平滑线 - 分析 进化 of the blog:

# get the Google Analytics (GA) data
gadata <- google_analytics(view_id,
  date_range = c(start_date, end_date),
  metrics = c("sessions"), # edit for other metrics
  dimensions = c("date"),
  anti_sample = TRUE # slows down the request but ensures data isn't sampled
)

# load required libraries
library(dplyr)
library(ggplot2)

# scatter plot with a trend line
gadata %>%
  ggplot(aes(x = date, y = sessions)) +
  geom_point(size = 1L, color = "steelblue") + # change size and color of points
  geom_smooth(color = "darkgrey", alpha = 0.25) + # change color of smoothed line and transparency of confidence interval
  theme_minimal() +
  labs(
    y = "Sessions",
    x = "",
    title= "Evolution of daily sessions",
    subtitle= paste0(format(start_date, "%b %d, %Y"), " to ", format(end_date, "%b %d, %Y")),
    caption = "Data: Google Analytics data of statsandr.com"
  ) +
  theme(plot.margin = unit(c(5.5, 15.5, 5.5, 5.5), "pt")) + # to avoid the plot being cut on the right edge
  scale_y_continuous(labels = scales::comma) # better y labels

(看 how to draw plots with the {ggplot2} package,或者与 {esquisse} addin 如果您不熟悉该软件包。)

正如您所见,4月底左右有巨大的流量高峰,一天内有近12,000名用户。是的,你读得很好,没有bug。博客文章“在Covid-19检疫期间下载免费的Springer书籍的包裹“病毒,并产生了几天的大量交通。几天后,每天返回到更正常水平。我们还在最后几个月(自8月底/ 9月初以来)遵守上升趋势,这表明博客在日常会议的数量方面正在增长。

Note that I decided to focus on the number of sessions and the number of page views in this section and the following ones, but you can always change to your preferred metrics by editing metrics = c("会议s") in the code. See all available metrics provided Google Analytics in this 文章.

每个频道会议

会心 人们如何来到你的博客 是一个非常重要的因素。以下是如何在A中可视化每频道每日会话的演变 线图:

# Get the data
trend_data <- google_analytics(view_id,
  date_range = c(start_date, end_date),
  dimensions = c("date"),
  metrics = "sessions",
  pivots = pivot_ga4("medium", "sessions"),
  anti_sample = TRUE # slows down the request but ensures data isn't sampled
)

# edit variable names
names(trend_data) <- c("Date", "Total", "Organic", "Referral", "Direct", "Email", "Social")

# Change the data into a long format
library(tidyr)
trend_long <- gather(trend_data, Channel, Sessions, -Date)

# Build up the line plot
ggplot(trend_long, aes(x = Date, y = Sessions, group = Channel)) +
  theme_minimal() +
  geom_line(aes(colour = Channel)) +
  labs(
    y = "Sessions",
    x = "",
    title= "Evolution of daily sessions per channel",
    subtitle= paste0(format(start_date, "%b %d, %Y"), " to ", format(end_date, "%b %d, %Y")),
    caption = "Data: Google Analytics data of statsandr.com"
  ) +
  scale_y_continuous(labels = scales::comma) # better y labels

我们看到大量的流量来自有机频道,这表明大多数读者在搜索引擎上查询后访问博客(主要是谷歌)。在我的情况下,我的大多数帖子都是教程,这有助于有特定问题的人,因此我的大多数流量来自有机搜索并不令人惊讶。

我们还注意到从推荐和直接渠道产生的一些小峰,这可能在每篇文章的出版日期发生。

我们还认为,日常会话的数量似乎似乎是一个经常发生的UPS和下降模式。那些是每周周期,周末较少的读者,这表明人们正致力于在本周(实际上是有意义的!)。

每周的课程

如上所示,交通似乎不同于 星期几。要进一步调查这一点,我们画了一个 箱形图 一周中每一天的会议数量:

# get data
gadata <- google_analytics(view_id,
  date_range = c(start_date, end_date),
  metrics = "sessions",
  dimensions = c("dayOfWeek", "date"),
  anti_sample = TRUE # slows down the request but ensures data isn't sampled
)

## Recoding gadata$dayOfWeek following GA naming conventions
gadata$dayOfWeek <- recode_factor(gadata$dayOfWeek,
  "0" = "Sunday",
  "1" = "Monday",
  "2" = "Tuesday",
  "3" = "Wednesday",
  "4" = "Thursday",
  "5" = "Friday",
  "6" = "Saturday"
)

## Reordering gadata$dayOfWeek to have Monday as first day of the week
gadata$dayOfWeek <- factor(gadata$dayOfWeek,
  levels = c(
    "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday",
    "Sunday"
  )
)

# Boxplot
gadata %>%
  ggplot(aes(x = dayOfWeek, y = sessions)) +
  geom_boxplot() +
  theme_minimal() +
  labs(
    y = "Sessions",
    x = "",
    title= "每周的课程",
    subtitle= paste0(format(start_date, "%b %d, %Y"), " to ", format(end_date, "%b %d, %Y")),
    caption = "Data: Google Analytics data of statsandr.com"
  ) +
  scale_y_continuous(labels = scales::comma) # better y labels

你可以看到有一些 异常值,可能(至少至少在于)到病毒的文章。为了说明,在去除被认为是潜在的异常值的点之后的相同曲线下方 四分位数(IQR) 标准(即晶须上方或下方的点),并且在几个视觉改进之后:

# boxplot
gadata %>%
  filter(sessions <= 3000) %>% # filter out sessions > 3,000
  ggplot(aes(x = dayOfWeek, y = sessions, fill = dayOfWeek)) + # fill boxplot by dayOfWeek
  geom_boxplot(varwidth = TRUE) + # vary boxes width according to n obs.
  geom_jitter(alpha = 0.25, width = 0.2) + # adds random noise and limit its width
  theme_minimal() +
  labs(
    y = "Sessions",
    x = "",
    title= "每周的课程",
    subtitle= paste0(format(start_date, "%b %d, %Y"), " to ", format(end_date, "%b %d, %Y")),
    caption = "Data: Google Analytics data of statsandr.com\nPoints > 3,000 excluded"
  ) +
  scale_y_continuous(labels = scales::comma) + # better y labels
  theme(legend.position = "none") # remove legend

在排除在3,000高于3,000的数据点之后,现在更容易看到中位数(框中的水平粗线表示)是星期三最高的,以及周六和周日最低。

然而,平日之间的会议差异与预期的那么大。对于感兴趣的读者,如果你想测试是否有一个 重大 在会话数量方面之间的差异,您可以执行 Anova..

每天和时间的会议

我们每周都看到了流量。下面的示例显示了流量的可视化,这次分解了 一周中的一天 在一个 密度图。在此绘图中,还添加了设备类型以供更多的见解。

## Get data by deviceCategory, day of week and hour
weekly_data <- google_analytics(view_id,
  date_range = c(start_date, end_date),
  metrics = c("sessions"),
  dimensions = c("deviceCategory", "dayOfWeekName", "hour"),
  anti_sample = TRUE # slows down the request but ensures data isn't sampled
)

## Manipulation using dplyr
weekly_data_sessions <- weekly_data %>%
  group_by(deviceCategory, dayOfWeekName, hour)

## Reordering weekly_data_sessions$dayOfWeekName to have Monday as first day of the week
weekly_data_sessions$dayOfWeekName <- factor(weekly_data_sessions$dayOfWeekName,
  levels = c(
    "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday",
    "Sunday"
  )
)

## Plotting using ggplot2
weekly_data_sessions %>%
  ggplot(aes(hour, sessions, fill = deviceCategory, group = deviceCategory)) +
  geom_area(position = "stack") +
  labs(
    title= "每天和时间的会议",
    subtitle= paste0(format(start_date, "%b %d, %Y"), " to ", format(end_date, "%b %d, %Y")),
    caption = "Data: Google Analytics data of statsandr.com",
    x = "Time",
    y = "Sessions",
    fill = "Device" # edit legend title
  ) +
  theme_minimal() +
  facet_wrap(~dayOfWeekName, ncol = 2, scales = "fixed") +
  theme(
    legend.position = "bottom", # move legend
    axis.text = element_text(size = 7) # change font of axis text
  ) +
  scale_y_continuous(labels = scales::comma) # better y labels

上面的情节表明:

  • 下午的交通增加,晚上下降
  • 交通从周一到周四最高,周六和周日最低

除此之外,由于设备类别的附加信息,我们还看到:

  • 平板电脑上的会话数量很低(与桌面和移动设备相比,桌面和移动设备上的次数很低),并且
  • 在整个日期,手机的会话数量似乎非常稳定,
  • 与桌面上的会话相比,在一天结束时最高。

每月课程和年份

在以下代码中,我们创建一个 巴格特 的数量 每月每月和年份:

# get data
df2 <- google_analytics(view_id,
  date_range = c(start_date, end_date),
  metrics = c("sessions"),
  dimensions = c("date"),
  anti_sample = TRUE # slows down the request but ensures data isn't sampled
)

# add in year month columns to dataframe
df2$month <- format(df2$date, "%m")
df2$year <- format(df2$date, "%Y")

# sessions by month by year using dplyr then graph using ggplot2 barplot
df2 %>%
  group_by(year, month) %>%
  summarize(sessions = sum(sessions)) %>%
  # print table steps by month by year
  # print(n = 100) %>%
  # graph data by month by year
  ggplot(aes(x = month, y = sessions, fill = year)) +
  geom_bar(position = "dodge", stat = "identity") +
  theme_minimal() +
  labs(
    y = "Sessions",
    x = "Month",
    title= "每月课程和年份",
    subtitle= paste0(format(start_date, "%b %d, %Y"), " to ", format(end_date, "%b %d, %Y")),
    caption = "Data: Google Analytics data of statsandr.com"
  ) +
  scale_y_continuous(labels = scales::comma) # better y labels

此巴格特允许容易地看到几个月内会话数量的演变,并比较不同年份的演变。

目前,由于博客仅在线自2019年12月以来,年份因素不相关。但是,我仍然为旧网站上工作的其他用户展示了可视化,并且还要提醒我未来的自我,在一年多的数据有数据时创建这个有趣的巴格特。

最佳执行页面

测量博客或网站表现时的另一个重要因素是 不同页面的页面次数. The top performing pages in terms of page views over the year can easily be found in Google Analytics (you can access it via Behavior > Site Content > All pages).

For the interested reader, here is how to get the data in R (note that you can change n = 7 in the code to change the number of top performing pages to display):

## Make the request to GA
data_fetch <- google_analytics(view_id,
  date_range = c(start_date, end_date),
  metrics = c("pageviews"),
  dimensions = c("pageTitle"),
  anti_sample = TRUE # slows down the request but ensures data isn't sampled
)

## Create a table of the most viewed posts
library(lubridate)
library(reactable)
library(stringr)

most_viewed_posts <- data_fetch %>%
  mutate(Title = str_trunc(pageTitle, width = 40)) %>% # keep maximum 40 characters
  count(Title, wt = pageviews, sort = TRUE)
head(most_viewed_posts, n = 7) # edit n for more or less pages to display
##                                      Title     n
## 1 A package to download free Springer b... 85684
## 2 可变类型和示例 - Stats a... 44951
## 3 r的描述性统计 - Stats a... 43621
## 4    Outliers detection in R - Stats and R 32560
## 5 The complete guide to clustering anal... 27184
## 6 Correlation coefficient and correlati... 21581
## 7                              Stats and R 16786

以下是如何在a中可视化顶部执行页面的表 巴格特:

# plot
top_n(most_viewed_posts, n = 7, n) %>% # edit n for more or less pages to display
  ggplot(., aes(x = reorder(Title, n), y = n)) +
  geom_bar(stat = "identity", fill = "steelblue") +
  theme_minimal() +
  coord_flip() +
  labs(
    y = "Page views",
    x = "Title",
    title= "Top performing pages in terms of page views",
    subtitle= paste0(format(start_date, "%b %d, %Y"), " to ", format(end_date, "%b %d, %Y")),
    caption = "Data: Google Analytics data of statsandr.com"
  ) +
  scale_y_continuous(labels = scales::comma) # better y labels

这使我是一个很好的首先概述了如何在页面浏览量方面执行的帖子,所以在某种意义上,人们发现有用的东西。例如,我从未想过帖子说明 统计中存在的不同类型的变量 (排名第2)在我写它时会非常感谢。

这是我与这个博客学到的东西:在撰写本文时,有一些帖子,我认为没有人会关心(以及我主要写作 个人注意),其他人认为人们会发现非常有用。然而,出版后几周几周后,有时我意识到它实际上完全相同。

时间正式化的页面视图

到那个时刻 比较博客帖子但是,这并不像简单。

基于上述Barplot而没有任何进一步的分析,我会得出结论,我的文章 变量类型 表现比其中更好 r中的异常值检测.

但是,如果我告诉您关于异常值检测的文章于8月11日发布,那么关于12月30日的关于变量类型的文章,您将同意该比较不再有很大的意义,因为这些文章的页面浏览量被计算在一个上不同的时间长度。还有人争辩说,最近的一篇文章有​​更短的时间来产生反向链接,因此将其与一篇旧帖子进行比较是不公平的,这有足够的时间被谷歌排名高。

为了使比较更“公平”,我们需要比较每个帖子的页面视图的数量 自发表日期以来。以下代码确实如此:3

  • 它为一堆页面提取日常数据,
  • 然后尝试检测他们的出版日期,
  • 时间 - 基于该假定的出版日期,按下每个页面的流量
  • 最后,从出版日期绘制日常流量,以及顶部的总累积流量 n pages
# figure out when a page actually launched by finding the
# first day where the page had at least 2 unique pageviews
first_day_pageviews_min <- 2

# exclude pages that have total traffic (daily unique pageviews) that are relatively low
total_unique_pageviews_cutoff <- 500

# set how many "days since publication" we want to include in our plot
days_live_range <- 180

# set number of top pages to display
n <- 7

# Create a dimension filter object
# You need to update the "expressions" value to be a regular expression that filters to
# the appropriate set of content on your site
page_filter_object <- dim_filter("pagePath",
  operator = "REGEXP",
  expressions = "/blog/.+"
)

# Now, put that filter object into a filter clause. The "operator" argument can be AND # or OR...but you have to have it be something, even though it doesn't do anything
# when there is only a single filter object.
page_filter <- filter_clause_ga4(list(page_filter_object),
  operator = "AND"
)

# Pull the GA data
ga_data <- google_analytics(
  viewId = view_id,
  date_range = c(start_date, end_date),
  metrics = "uniquePageviews",
  dimensions = c("date", "pagePath"),
  dim_filters = page_filter,
  anti_sample = TRUE # slows down the request but ensures data isn't sampled
)

# Find the first date for each post. This is actually a little tricky, so we're going to write a
# function that takes each page as an input, filters the data to just include those
# pages, finds the first page, and then puts a "from day 1" count on that data and
# returns it.
normalize_date_start <- function(page) {

  # Filter all the data to just be the page being processed
  ga_data_single_page <- ga_data %>% filter(pagePath == page)

  # Find the first value in the result that is greater than first_day_pageviews_min. In many
  # cases, this will be the first row, but, if there has been testing/previews before it
  # actually goes live, some noise may sneak in where the page may have been live, technically,
  # but wasn't actually being considered live.
  first_live_row <- min(which(ga_data_single_page$uniquePageviews > first_day_pageviews_min))

  # Filter the data to start with that page
  ga_data_single_page <- ga_data_single_page[first_live_row:nrow(ga_data_single_page), ]

  # As the content ages, there may be days that have ZERO traffic. Those days won't show up as
  # rows at all in our data. So, we actually need to create a data frame that includes
  # all dates in the range from the "publication" until the last day traffic was recorded. There's
  # a little trick here where we're going to make a column with a sequence of *dates* (date) and,
  # with a slightly different "seq," a "days_live" that corresponds with each date.
  normalized_results <- data.frame(
    date = seq.Date(
      from = min(ga_data_single_page$date),
      to = max(ga_data_single_page$date),
      by = "day"
    ),
    days_live = seq(min(ga_data_single_page$date):
    max(ga_data_single_page$date)),
    page = page
  ) %>%

    # Join back to the original data to get the uniquePageviews
    left_join(ga_data_single_page) %>%

    # Replace the "NAs" (days in the range with no uniquePageviews) with 0s (because
    # that's exactly what happened on those days!)
    mutate(uniquePageviews = ifelse(is.na(uniquePageviews), 0, uniquePageviews)) %>%

    # We're going to plot both the daily pageviews AND the cumulative total pageviews,
    # so let's add the cumulative total
    mutate(cumulative_uniquePageviews = cumsum(uniquePageviews)) %>%

    # Grab just the columns we need for our visualization!
    select(page, days_live, uniquePageviews, cumulative_uniquePageviews)
}

# We want to run the function above on each page in our dataset. So, we need to get a list
# of those pages. We don't want to include pages with low traffic overall, which we set
# earlier as the 'total_unique_pageviews_cutoff' value, so let's also filter our
# list to only include the ones that exceed that cutoff. We also select the top n pages
# in terms of page views to display in the visualization.
library(dplyr)
pages_list <- ga_data %>%
  group_by(pagePath) %>%
  summarise(total_traffic = sum(uniquePageviews)) %>%
  filter(total_traffic > total_unique_pageviews_cutoff) %>%
  top_n(n = n, total_traffic)

# The first little bit of magic can now occur. We'll run our normalize_date_start function on
# each value in our list of pages and get a data frame back that has our time-normalized
# traffic by page!
library(purrr)
ga_data_normalized <- map_dfr(pages_list$pagePath, normalize_date_start)

# We specified earlier -- in the `days_live_range` object -- how many "days since publication" we
# actually want to include, so let's do one final round of filtering to only include those
# rows.
ga_data_normalized <- ga_data_normalized %>% filter(days_live <= days_live_range)

现在我们的数据已准备就绪,我们创建了两个可视化:

  1. 自发布以来一天的页面浏览量:此图显示了特定内容的兴趣如何降低。如果它没有作为其他帖子迅速下降,这意味着你正在得到 持续 value from it
  2. 累积 自发布以来一天的页面浏览量:此曲线可用于将博客帖子与同一地面进行比较,因为根据发布日期显示页面次数。要查看哪些页面随时间产生最多的流量,只需从上到下看(在绘图的右边缘)

Note that both plots use the {plotly} package to make them interactive so that you can mouse over a line and find out exactly what page it is (together with its values). The interactivity of the plot makes it also possible to zoom in to see, for instance, the number of page views in the first days after publication (instead of the default length of 180 days),4 或放大以仅查看以下/高于特定阈值的页面视图的数量的演变。

# Create first plot
library(ggplot2)

gg <- ggplot(ga_data_normalized, mapping = aes(x = days_live, y = uniquePageviews, color = page)) +
  geom_line() + # The main "plot" operation
  scale_y_continuous(labels = scales::comma) + # Include commas in the y-axis numbers
  labs(
    title= "Page views by day since publication",
    x = "Days since publication",
    y = "Page views",
    subtitle= paste0(format(start_date, "%b %d, %Y"), " to ", format(end_date, "%b %d, %Y")),
    caption = "Data: Google Analytics data of statsandr.com"
  ) +
  theme_minimal() + # minimal theme
  theme(
    legend.position = "none", # remove legend
  )

# Output the plot, wrapped in ggplotly so we will get some interactivity in the plot
library(plotly)
ggplotly(gg, dynamicTicks = TRUE)

上面的剧情再次显示出了病毒(橙色线)的帖子的巨大尖峰。如果我们放大仅包含以下1500的页面视图,帖子之间的比较更容易,我们看到:

  • 帖子上 Coronavirus上的100个资源 (紫线)在前50天内的其他帖子产生了比较更多的流量(\(\ \ \) 发表后1个月和3周)。然而,交通逐渐减少到180天后(\(\ \ \) 6个月),它吸引了比其他表演职位的交通较少。
  • 帖子上 r中的异常值检测 (蓝线)在出版后的第一周并没有得到很多关注。但是,它逐渐产生了越来越多的交通到60天后(\(\ \ \) 2个月)出版后,它实际上产生了比任何其他帖子更多的流量(以及相对较大的边缘)。
  • 帖子上 r相关系数和相关性测试 (绿线)花了大约100天(\(\ \ \) 3个月和1周)起飞,但之后它会产生很多交通。在分析最近的帖子时,这很有趣,因为他们实际上可能遵循相同的趋势。
# Create second plot: cumulative
gg <- ggplot(ga_data_normalized, mapping = aes(x = days_live, y = cumulative_uniquePageviews, color = page)) +
  geom_line() + # The main "plot" operation
  scale_y_continuous(labels = scales::comma) + # Include commas in the y-axis numbers
  labs(
    title= "Cumulative page views by day since publication",
    x = "Days since publication",
    y = "Cumulative page views",
    subtitle= paste0(format(start_date, "%b %d, %Y"), " to ", format(end_date, "%b %d, %Y")),
    caption = "Data: Google Analytics data of statsandr.com"
  ) +
  theme_minimal() + # minimal theme
  theme(
    legend.position = "none", # remove legend
  )

# Output the plot, wrapped in ggplotly so we will get some interactivity in the plot
ggplotly(gg, dynamicTicks = TRUE)

与之前的情节相比,这个展示了这个 累积 自发布日期以来的页面浏览量。

不考虑到病毒的帖子,顺便说一下,这不再真正产生了很多流量(这是有道理的,因为斯普林特的令人难以置信的运动在Covid-19检疫期间免费提供他们的书籍已经结束),我们看到:

  • 帖子上 异常值检测 已经超越了帖子 Coronavirus上的顶级资源 在大约120天后的页面次数的累积数量方面(\(\ \ \) 4个月)出版后,这表明人们正在研究这个具体问题。我记得我写了这篇文章,因为那时,我不得不处理r中的异常值的问题,我没有在网上找到一个整洁的解决方案。所以我想,特定主题上的资源缺少的事实有助于吸引寻找他们问题答案的访客。
  • 在剩下的帖子中,在180天内,在累计页面次数的累计次数中排名\(\ \ \) 6个月)出版后是以下内容:
    1. r相关系数和相关性测试
    2. 用手和r的聚类分析
    3. r的描述性统计
    4. 可变类型和示例

到目前为止的分析让您已经对博客的表现良好了解。但是,对于感兴趣的读者,我们在以下部分中显示了其他重要指标。

Page浏览量

在下文中,我们有兴趣看到 交通来自哪里。如果您正在运营业务或电子商务,可以更加有趣,更有兴趣,更重要,更重要。

# get GA data
data_fetch <- google_analytics(view_id,
  date_range = c(start_date, end_date),
  metrics = "pageviews",
  dimensions = "country",
  anti_sample = TRUE # slows down the request but ensures data isn't sampled
)

# table
countries <- data_fetch %>%
  mutate(Country = str_trunc(country, width = 40)) %>% # keep maximum 40 characters
  count(Country, wt = pageviews, sort = TRUE)
head(countries, n = 10) # edit n for more or less countries to display
##           Country      n
## 1   United States 131306
## 2           India  38800
## 3         Belgium  32983
## 4  United Kingdom  25833
## 5          Brazil  18961
## 6         Germany  17851
## 7           Spain  17355
## 8          Canada  13880
## 9          Mexico  12882
## 10    Philippines  12540

在页面浏览方面可视化顶部国家的此表 巴格特:

# plot
top_n(countries, n = 10, n) %>% # edit n for more or less countries to display
  ggplot(., aes(x = reorder(Country, n), y = n)) +
  geom_bar(stat = "identity", fill = "steelblue") +
  theme_minimal() +
  coord_flip() +
  labs(
    y = "Page views",
    x = "Country",
    title= "Top performing countries in terms of page views",
    subtitle= paste0(format(start_date, "%b %d, %Y"), " to ", format(end_date, "%b %d, %Y")),
    caption = "Data: Google Analytics data of statsandr.com"
  ) +
  scale_y_continuous(labels = scales::comma) + # better y labels
  theme(plot.margin = unit(c(5.5, 7.5, 5.5, 5.5), "pt")) # to avoid the plot being cut on the right edge

我们看到来自美国的读者占据了最大的页面浏览量(其实实际上很多!),比利时(我国)在页面浏览量方面排名第三。

鉴于美国人口远远大于比利时人口(\(\ \ \) 3.31亿人比较 \(\ \ \) 11.5百万人分别),以上结果并不令人惊讶。同样,为了更好的比较,在比较国家时会考虑人口的规模是有趣的。

实际上,这可能是大量的交通来自一个拥有众多人口的国家,但是每个人(或每100,000名居民)的页面次数的数量较高,对于另一个国家来说更高。这些有关顶级表演国家的信息在页面视图中 每人 可以给你见解 最狂热的读者来自哪个国家。这超出了本文的范围,但您可以看到包含有关这些人口大小的信息的图的示例 Covid-19可视化。我建议将相同的方法应用于上面的图,以便更好地进行比较。

如果您正在考虑在比较国家时在包括人口大小的额外步骤,我相信也要更好地考虑到每个国家的计算机访问信息。如果我们以印度为例:在撰写本文时,其人口差不多为1.4 十亿。然而,获得计算机的印度人的百分比无疑低于美国或比利时(再次,至少在此刻)。通过比较页面视图的数量来比较国家将更有意义 每个人都可以访问电脑.5

浏览器信息

有关更多技术方面,您也可以对数量感兴趣 浏览器的页面浏览量。这可以通过以下Barplot可视化:

# get data
browser_info <- google_analytics(view_id,
  date_range = c(start_date, end_date),
  metrics = c("pageviews"),
  dimensions = c("browser"),
  anti_sample = TRUE # slows down the request but ensures data isn't sampled
)

# table
browser <- browser_info %>%
  mutate(Browser = str_trunc(browser, width = 40)) %>% # keep maximum 40 characters
  count(Browser, wt = pageviews, sort = TRUE)

# plot
top_n(browser, n = 10, n) %>% # edit n for more or less browser to display
  ggplot(., aes(x = reorder(Browser, n), y = n)) +
  geom_bar(stat = "identity", fill = "steelblue") +
  theme_minimal() +
  coord_flip() +
  labs(
    y = "Page views",
    x = "Browser",
    title= "Which browsers are our visitors using?",
    subtitle= paste0(format(start_date, "%b %d, %Y"), " to ", format(end_date, "%b %d, %Y")),
    caption = "Data: Google Analytics data of statsandr.com"
  ) +
  scale_y_continuous(labels = scales::comma) # better y labels

大多数访问都是预期的,来自Chrome,Safari和Firefox浏览器。

用户订婚器

也可能有兴趣检查 用户如何订婚 在不同类型的设备上。为此,我们绘制3图表描述:

  1. 有多少会议 由不同类型的设备制成
  2. 页面上的平均时间 (以秒为单位)通过设备类型
  3. 每个会话的页面浏览量 by device type
# GA data
gadata <- google_analytics(view_id,
  date_range = c(start_date, end_date),
  metrics = c("sessions", "avgTimeOnPage"),
  dimensions = c("date", "deviceCategory"),
  anti_sample = TRUE # slows down the request but ensures data isn't sampled
)

# plot sessions by deviceCategory
gadata %>%
  ggplot(aes(deviceCategory, sessions)) +
  geom_bar(aes(fill = deviceCategory), stat = "identity") +
  theme_minimal() +
  labs(
    y = "Sessions",
    x = "",
    title= "Sessions per device",
    subtitle= paste0(format(start_date, "%b %d, %Y"), " to ", format(end_date, "%b %d, %Y")),
    caption = "Data: Google Analytics data of statsandr.com",
    fill = "Device" # edit legend title
  ) +
  scale_y_continuous(labels = scales::comma) # better y labels

从上面的情节,我们看到大多数读者从桌面访问博客,以及来自平板电脑的少数读者。

# add median of average time on page per device
gadata <- gadata %>%
  group_by(deviceCategory) %>%
  mutate(med = median(avgTimeOnPage))

# plot avgTimeOnPage by deviceCategory
ggplot(gadata) +
  aes(x = avgTimeOnPage, fill = deviceCategory) +
  geom_histogram(bins = 30L) +
  scale_fill_hue() +
  theme_minimal() +
  theme(legend.position = "none") +
  facet_wrap(vars(deviceCategory)) +
  labs(
    y = "Frequency",
    x = "Average time on page (in seconds)",
    title= "Average time on page per device",
    subtitle= paste0(format(start_date, "%b %d, %Y"), " to ", format(end_date, "%b %d, %Y")),
    caption = "Data: Google Analytics data of statsandr.com"
  ) +
  scale_y_continuous(labels = scales::comma) + # better y labels
  geom_vline(aes(xintercept = med, group = deviceCategory),
    color = "darkgrey",
    linetype = "dashed"
  ) +
  geom_text(aes(
    x = med, y = 90,
    label = paste0("Median = ", round(med), " seconds")
  ),
  angle = 90,
  vjust = 2,
  color = "darkgrey",
  size = 3
  )

从上面的情节,我们看到:

  • 对于在每页上花费低平均时间的读者,他们中的大多数都在平板电脑上(在平板电脑小平面中看到距离左右0秒)
  • 除了一些 异常值 在左右750秒(= 12分30秒)上移动,桌面和手机上读卡器页面的平均时间的分布非常相似,平均在页面上主要在100秒之间(= 1分40秒)和350秒(= 5分50秒)
  • 非常令人惊讶的是,在页面上花费的平均时间的中位数对于手机上的游客略高于桌面上的游客(参见桌面和移动刻面中的中位数的虚线垂直线)。这表明,虽然更多人访问桌面的博客,但似乎 手机上的人们每页花更多时间。鉴于我的大多数文章包括R代码并要求计算机运行代码,我发现这一点非常令人惊讶。因此,我预计人们会在桌面上花费更多时间,因为在移动时,他们会很快扫描这篇文章,而在桌面上,他们会仔细阅读文章并尝试在他们的计算机上重现代码。6

鉴于此结果,也有趣的是说明 会话期间的页面次数,由设备类型表示。

事实上,可能是移动支出的访问者,平均每页都有更多时间 但桌面上的人们每次会议访问更多页面。我们通过密度图验证了这一点,并且为了更好的可读性,我们排除了2.5页面视图/会话以上的数据点,我们排除了平板电脑的访问:

# GA data
gadata <- google_analytics(view_id,
  date_range = c(start_date, end_date),
  metrics = c("pageviewsPerSession"),
  dimensions = c("date", "deviceCategory"),
  anti_sample = TRUE # slows down the request but ensures data isn't sampled
)

# add median of number of page views/session
gadata <- gadata %>%
  group_by(deviceCategory) %>%
  mutate(med = median(pageviewsPerSession))

## Reordering gadata$deviceCategory
gadata$deviceCategory <- factor(gadata$deviceCategory,
  levels = c("mobile", "desktop", "tablet")
)

# plot pageviewsPerSession by deviceCategory
gadata %>%
  filter(pageviewsPerSession <= 2.5 & deviceCategory != "tablet") %>% # filter out pageviewsPerSession > 2.5 and visits from tablet
  ggplot(aes(x = pageviewsPerSession, fill = deviceCategory, color = deviceCategory)) +
  geom_density(alpha = 0.5) +
  scale_fill_hue() +
  theme_minimal() +
  labs(
    y = "Frequency",
    x = "Page views per session",
    title= "Page views/session by device",
    subtitle= paste0(format(start_date, "%b %d, %Y"), " to ", format(end_date, "%b %d, %Y")),
    caption = "Data: Google Analytics data of statsandr.com\nPoints > 2.5 excluded",
    color = "Device", # edit legend title
    fill = "Device" # edit legend title
  ) +
  scale_y_continuous(labels = scales::comma) + # better y labels
  geom_vline(aes(xintercept = med, group = deviceCategory, color = deviceCategory),
    linetype = "dashed",
    show.legend = FALSE # remove legend
  ) +
  geom_text(aes(
    x = med, y = 2.75,
    label = paste0("Median = ", round(med, 2), " page views/session"),
    color = deviceCategory
  ),
  angle = 90,
  vjust = 2,
  size = 3,
  show.legend = FALSE # remove legend
  )

最后一个剧情证实了我们的想法,即虽然手机上的人们似乎在每页上花费更多时间, 桌面上的人们倾向于每次会议访问更多页面.

(人们可能想知道为什么我选择比较中位数而不是手段。主要原因是不是这里考虑的所有分布 钟形 (特别是在平板电脑上的数据)并且有很多 异常值。在这些情况下,平均值通常不是最合适的 描述性统计 中位数是代表这些数据的更强大的方式。对于感兴趣的读者,请参阅有关的说明 平均和中位之间的区别以及每种措施更合适的上下文。)

这是分析部分的结尾。当然,许多可视化和数据分析是可能的,具体取决于跟踪的网站以及分析师的营销专业知识。这是一个可能的概述,我希望它会给你一些想法,以进一步探索你的Google分析数据。明年,我还可以包括预测并进行年度比较。另请参阅此内容的一些例子 github存储库 还有这个 网站.

作为一个侧面笔记,我想补充一下:即使跟踪博客的性能也很重要,了解如何吸引访客以及他们如何与您的网站互动,我也相信 看看您的Google Analytics统计数据通常不是最佳的,也不是理智的。

谈论个人经历:在博客的开头,我曾经经常看过实时和观众的访客人数。我有点沉迷于知道现在有多少人在我的博客上,我经常检查它是否比访客人数比前一天表现得更好。我记得在我觉得我浪费我的时间的第一周,我花了这么多时间看这些指标。而我浪费的时间看着我的Google Analytics统计数据丢失而不是为博客创造良好的质量内容,研究我的论文/课程或其他项目。

因此,当我意识到时,我从我的智能手机中删除了Google Analytics应用程序,并强迫自己每月不超过一次查看我的统计数据(只是为了确保没有修复的重要问题)。从那一刻起,我停下来浪费我无法控制的事情的时间,我对写作文章感到更多的满足,因为我正在为自己写作,而不是为了看到人们阅读他们的人。这种变化就像一个救济,我现在更满意我对这个博客的工作相比,而第一周或几个月。

每个人都不同,独特,所以我不是说你应该这样做。但是,如果您觉得您的统计数据看起来过于多大,有时会在写作中失去动力,也许这是一个潜在的解决方案。

内容

既然我们已经看到我们如何分析Google Analytics数据并追踪网站或博客的性能,我想分享关于内容创建,内容分发和未来计划的一些想法。

寻找主题

我与博客面临的最大挑战之一是 创建适当的内容。在最好的情况下,我想:

  • 创建 有用 content
  • 关于主题我真的 熟悉的 with,
  • 哪一个我 请享用 and
  • 哪个 适合博客.

通过仅共享关于我熟悉的主题的文章,写入过程更容易和更快。事实上,我在大学教授的大多数文章我写了我在大学教学的封面主题,所以当我决定写它时已经完成了大部分初步研究。此外(而这并不可忽略),来自学生的问题和收入允许我看到我应该在写作时应该关注的那些点,以及如何展示它使其可以访问和对大多数人来说可接近。

此外,通过提出我的思想公众,我经常有机会用其他观点面对他们,这让我甚至进一步研究这个话题。这反过来又加速了写入相关主题时更多的写入过程。

我也倾向于只写下我喜欢的东西或者我感兴趣。我更喜欢质量超过数量,因此根据主题的深度,从A到Z写一篇文章需要很长时间。由于它需要时间(即使没有考虑到出版后花费的时间)而且我有一个全职工作,我真的专注于我喜欢的主题,以便继续将这个博客视为一种快乐的来源,而不是作为工作或义务。

我只写关于我熟悉的事情的事实,我喜欢和我有空闲时间(主要取决于与我的博士学论文相关的正在进行的项目),让我努力遵循定期的帖子。这就是为什么我的写作时间表在第一年期间有点不一致,并且在将来可能类似,因为我不希望能够强迫自己写作。7

内容分发

即使我们都同意博主应该 先写自己 而不是为了拥有大量读者,当您的内容被他人读取时,仍然很感激。

所以虽然我不喜欢滥用自我推广,但我不觉得分享我的博客帖子到所有现有的Facebook,LinkedIn和Reddit组,以某种方式需要 通知你已经写了一些东西.

出于这个原因,我创造了一个 推特账户 在博客上发布后立即分享新帖子的地方。除了在Twitter上发布它们,我还通过电子邮件与订阅者的人分享链接 通讯 of the blog.

我也设法录制了我的内容 中等的 通过朝向数据科学出版物, R-Bloggers.每周r。我的观众的不可忽略部分来自这些推荐,特别是在出版后的几天内。

通过这种方式分发内容,我不觉得咄咄逼人(我想要避免所有费用!)因为人们由自己决定收到我发布的内容(例如,他们订阅了通讯,他们遵循Twitter上的博客,他们选择阅读博客聚合器等)。所以在某种意义上,我不分发我的内容“如果没有他们的事先同意”,他们总是可以选择不再看到我的帖子了。

但是,正如你所看到的那样 每个频道的会话数量,你看到大多数读者来自有机频道,从而从搜索引擎中。对于此频道,除了创建质量内容(以及SEO中的一些基本知识),我还没有控制它的呈现方式,也没有向人分发给人。对于此频道,它基本上是搜索引擎算法,决定促进我的内容,如果他们这样做,促进了。我对排名因素的唯一控制权只是 创建质量内容.

因此,即使我认为拥有内容分发策略肯定有助于到达更多人和越来越多的博客,它就不会成为一切。在SEO和营销的初学者看来,创造质量内容是我帖子的最佳策略。

对于这种非常具体的原因,现在我觉得我已经解决了一个体面的分销策略,我不再在这个问题上度过我的能量和时间。

所以我只需尝试在我的博客上享受写作,其余的最终将遵循。如果没有,我仍然从这个博客中学习了很多,所以我没有像浪费时间那样看到它。

关于广告的一个小笔记

我知道,从博客中赚钱的简单方法是运行广告,我明白人们会这样做,如果它是有利可图的。但是,我经常发现广告过于侵入或烦人,我个人不喜欢阅读包含许多广告的博客帖子。

要使阅读过程尽可能令人愉快,正如您所看到的,我没有在我的博客上显示任何广告。只要运行本网站的成本和相关的开源项目(例如,我的 闪亮的应用程序等等)不是太高,我不希望包括广告。

如果在未来的成本增加,我仍然会尽量尽可能地避免涂抹广告,我会尽力依赖 赞助计划& donations 和上 付费侧项目 对于需要帮助他们的统计分析的人。

未来的计划

在一年的博客之后,我问自己:

我想要什么 statsandr.com. to be?

正如已经说过的那样,只要我喜欢写东西,我就会对这个博客充满热情,我将继续。这对我来说非常重要。

除此之外,我希望它成为一个地方 分享知识。统计和r(和数据科学一般)的领域正在以极快的节奏发展 - 越来越多的人有许多有趣的事情。

此外,自发射此博客以来,我学到了很多东西。但 在合作时,我学会了更多 与别人(见例如这些 合作)。我看到这么多学习机会在合作时,我很乐意将此博客视为分享知识的地方,但 不仅是我的知识.

更精确,我很想知道想要与我合作的其他研究人员,统计学家,R恋人,数据科学家,作者等。最后,这可能导致:

  • a 客人邮政 如果您对您想要写的内容有一个好主意,但需要一种方法来分享它(并且自从您通过这篇文章在过去一年中访问我的Google Analytics数据,您可以了解将会有所了解的访客人数查看您的内容),
  • 如果您认为我们的技能和知识是互补的,则写在一起的内容(见所有 文章 有关我喜欢写的概述),
  • 一段代码,一个r封装,a 可视化 或者 闪亮的应用程序 您想一起创建(或仅共享),
  • 一本书或课程 统计数据 和/或 R,
  • 或者你有什么想法(我对新想法和挑战开放)。

有了这篇文章,您可以看到博客的数字和观众。与我所有的 文章,你可以看到我的优势和弱点。

所以我将通过说,如果有人愿意,我将完成这一部分 一起工作 (这不需要巨大),你可以永远 联络我 或在这篇文章结束时发表评论。我期待着您的回音。

谢谢注释

最后但并非最不重要的是,我也想留下一份短暂的谢谢你注意到数据科学,R-Bloggers和R每周队伍,这些团队在各自的出版物中交叉发布了大多数文章,因此让我分享我的思想一个更大而非常知识的观众。

此外,我要感谢所有活跃的读者到目前为止的意见,建设性的反馈和支持。我期待着通过这篇博客分享更多的质量内容,我希望它会对你们中的许多人来说都是有用的,并并行地对我有用。

特别感谢 Mark Edmondson., the author of the {googleAnalyticsR} package and all people who wrote 教程 使用包装,将其用作此博客文章的灵感。更广泛地,谢谢也归功于开源社区,在学习R.

Thanks for reading. I hope that you learned how to track the performance of your website or blog in R using the {googleAnalyticsR} package. See you next year for a second 审查并且与此同时,如果您维护博客,我真的很高兴听到您如何跟踪其性能。随意通过以下评论让我知道!

一如既往,如果您有问题或与本文所涵盖的主题相关的建议,请将其添加为评论,以便其他读者可以从讨论中受益。


  1. 非常感谢 Rstudio博客 for the inspiration.↩︎

  2. 查看更多方法 安装和加载R包.↩︎

  3. 非常感谢 Dartisticy.com 对于代码。请注意,为了更好的绘图可读性,我略微编辑代码:(i)只显示顶部 n 页面 in terms of traffic instead of all pages, (ii) to change the theme to theme_minimal() 和 (iii) to make the axis ticks dynamic when zooming in or out (in the ggplotly() function).↩︎

  4. 请注意,在代码中也可以更改180天的默认期限。↩︎

  5. 如果没有易于使用计算机的人员的百分比,这可能需要一些假设。但是,我相信,它仍然比仅考虑到人口规模更合适 - 特别是在与发展中国家发达的比较时。↩︎

  6. 至少这就是我在读取移动与桌面上阅读它们的博客时所做的。↩︎

  7. 但请注意,该研究表明,编写的调度时间是富有成效写作的好方法(西尔维亚,2019年)。这就是为什么,与我的博客不同,我在我的日历中设置了定期的写作句号(我试图坚持下来,无论我在那个时间忙)致力于我的博士论文。 ↩︎



喜欢这篇文章?

获取更新 每次发布新文章。
任何垃圾邮件都没有任何垃圾邮件。
分享: