1. 程式人生 > >The Anatomy of a `.track()` Call

The Anatomy of a `.track()` Call

Maintaining a consistent naming convention is a great way to ensure your analytics data is clean and easy to use. But knowing how to send a .track() call can tremendously step up your analytics game—you’ll be able to create funnels and analyze cohorts, while still having the freedom to explore your data. Not only that, but the code footprint is smaller, so it’s easier to manage and maintain, especially if you’re using a

tracking plan.

This week, we’ll show you that you can answer anything and keep your analytics scope manageable if you include the right data in your .track() call. We’ll also provide examples and reveal a little bit about what is going on beneath the hood.

Event-based Analytics

Almost all analytics and marketing automation tools today are event-based. Events are actions that are triggered by something your customer performs on your site or app. Examples including Account Created

or Song Played. Every time this event occurs, a new record is created in the analytics database.

To record that action, most tools have a .track() call (it may not be called “track”—this is what Segment’s API uses—but there are equivalents). If you’re smart and consistent with what you include in these .track()

calls, your analysis can be flexible and powerful.

What is a ‘.track()’ call?

A .track() call captures the most atomic piece of data in an analytics database. It represents one unique row; an action that a user performed on your site or app, with the contextual information like when, where, and (sometimes) how it happened, nested as properties. With an aggregate of these records, you can understand overall product usage, funnels, and trends. Or, you can trigger personalized messages to specific set of your users with your email tool.

Here is the anatomy of a .track() call in three different flavors: Segment, Mixpanel, and Google Analytics. Note we’re following the Object Action Framework that we laid out in the previous Academy lesson, with the property names in snake_case.

Segment (analytics.js)

analytics.track("Song Played", { // the event or action the user performed
  name: "What Do You Mean", // specifics of the event
  artist_name: "Justin Bieber"
  album: "Purpose",
  label: "Def Jam - School Boy",
  genre: "Dance Pop"
});

Google Analytics (analytics.js)

ga('send', 'event', {
  eventAction: 'Song Played',
  eventCategory: 'All'
});

Mixpanel

window.mixpanel.track("Song Played", { // the event or action the user performed
  name: "What Do You Mean", // specifics of the event
  artist_name: "Justin Bieber"
  album: "Purpose",
  label: "Def Jam - School Boy",
  genre: "Dance Pop"
});

The .track() call captures more than just the event name. It includes the timestamp, the user who performed the action, and other contextual specifics that help you conduct your analysis later.

All .track() calls include the following: userId, event, properties, and timestamp:

  • userId: you may have noticed that userId was never explicitly sent in the .track() examples above. That’s because these calls were all sent using client-side Javascript libraries, where userId is automatically set and sent behind the scenes (we’ll dive into this more next week). What you should know is that the userId is a unique identifier of the user and that it’s important to tie events back to the user. This allows you to follow a single customer’s events over time for cohort and other useful analyses.
  • event: the event name. You can create trends and usage reports based on these names. This is why it’s important to stick to a consistent naming convention, so it’s easier to do analysis without having to second guess if the event is the right one. See our last lesson.
  • properties: this is a set of keys and values that provide more context around the event itself. For example, which song was played. These values are useful to provide additional dimensions upon which you can slice and dice your data. As such, it’s better to use them for specifics and keep the event names general.
  • sent_at (time stamp): again, this one wasn’t explicitly sent. However, all libraries will automatically record the time and send it. This is useful for looking at events over time or ordering events chronologically.

Though it may be confusing what pieces of data to send in each part of the .track() call, here is a peek at the underlying technology that informs what analyses is achievable.

How do they get stored?

Most analytics services will store each record as a row in a relational database (we won’t get too in the weeds, since the technical details can vary amongst companies). But this database allows the analytics tools to be able to parse your data based on your event type and any combination of its properties.

Relational databases are like spreadsheets—each row is a unique event and columns are property names. Note that since the properties can vary depending on the event, each event will have its own table. We’ll show how you can easily pivot and group this data in the analytics tools.

This is an example of the Song Played table:

here is a sample table of songs played

Given this “spreadsheet”, we can quickly count the total number of songs played, get the weekly count of songs played over time, or even count the number of songs played from a specific artist.

But how is the ability to group data across various column names useful in analytics tools?

In Mixpanel, we can group and count actions based on the properties we set in the .track() call (Mixpanel calls them “Events”) and contextual information their library automatically passes (Browser, Browser Version, etc.).

here is a sample mixpanel of songs played

This allows us to easily create charts to see usage trends over time. Moreover, Mixpanel allows you to do cohort and funnel analysis, where you have the flexibility to group events across properties and other “columns”. (More on Mixpanel here.)

Other tools offer similar flexibility. Here is how you can create elaborate customer segments in Customer.IO, a popular email tool:

here is a sample customer.io of songs played

Here we can create an email list of Justin Bieber fans. We can then send targeted emails about Justin Bieber to this list. (For more information on how to use Customer.IO, visit their help section! Here’s also a list of other email and marketing automation tools.)

These tools are able to pivot and group easily based on the event name, properties, userId, and other column names. As such, the key value pairs that are sent in properties are tremendously powerful: they are the dimensions that allow you to slice and dice data, create cohorts of your users, and analyze sub trends easily over time.

Examples of Tracking Do’s and Don’t’s

Here are some examples of Do’s and Don’ts with .track() calls.

Consolidate Events

DON’T use multiple specific event names.

analytics.track("Song Played - Formation by Beyoncé");

This means in your downstream analysis, you’d only be able to figure out how many times each song was played, which isn’t as useful as knowing that a song was played.

DO consolidate events to a single event name with multiple values in the properties.

analytics.track("Song Played", {
  name: "Formation",
  artist: "Beyoncé"
});

This way, you’d be able to see how many times a song is played. Moreover, you’d be able to slice the data of “Songs Played” by any of the properties—i.e. you can figure out how many times a Beyoncé song was played or how many times her “Formation” was played. More flexible analysis!

No Nested Properties

DON’T send “nested” properties:

analytics.track("Song Played", {
  name: "Formation",
  artist: "Beyoncé"
  user: {
    name: "Andy",
    email: "[email protected]",
    twitter: "andyjiang"
  }
});

DO send “flat” properties:

analytics.track("Song Played", {
  name: "Formation",
  artist: "Beyoncé",
  name: "Andy",
  email: "[email protected]",
  twitter: "andyjiang"
});

There are many tools that handle nested properties differently—some will flatten for you, others will keep the data hierarchy. Because this is treated inconsistently, it’s best to be intentional about how you send the properties from the get go. Send it flat so that you’ll know how every tool will treat the data!

Reducing Complexity

Part of tracking implementation is translating your business questions to building a tracking plan and figuring out exactly what to send in the .track() call. Understanding how properties are used in slicing and dicing your data downstream can inform your data collection strategy.

Many times, you can use fewer event names to answer the same thing, especially when you include relevant data in the properties. This way, you can simplify your implementation and still effectively learn about your customers.

Have any tips or tricks related sending analytics calls? Let us know on Twitter!

相關推薦

The Anatomy of a `.track()` Call

Maintaining a consistent naming convention is a great way to ensure your analytics data is clean and easy to use. But knowing how to send a .track

The Anatomy Of A React Redux App

The Anatomy Of A React Redux AppIf you inspect the source of a React Redux app, it could be overwhelming. But there is a method to the madness and it becom

POJ 2553 The Bottom of a Graph(強連通分量)

margin target 代碼 not push ret dsm ng- http POJ 2553 The Bottom of a Graph 題目鏈接 題意:給定一個有向圖,求出度為0的強連通分量 思路:縮點搞就可以 代碼: #include <

The Bottom of a Graph

ive limit rtai assume ted can hab spa mean                poj——The Bottom of a Graph

return three values that can be the lengths of the sides of a triangle,

static use prev element and hat [] sin sha 這是return numbers, return value 剛簡單, 首先sort ,然後遍歷,看當前值+ 前值> 後值 class CountTriangles { /

【poj2553】The Bottom of a Graph(強連通分量縮點)

targe ring sin spa const ostream 連通 stream pty 題目鏈接:http://poj.org/problem?id=2553 【題意】 給n個點m條邊構成一幅圖,求出所有的sink點並按順序輸出。sink點是指該點能到達的點反過來

#748 – 獲得按下時對應位置點的大小(Getting the Size of a Contact Point during Raw Touch)

ini bounds event view hup main.c .cn hand phoenix 原文:#748 – 獲得按下時對應位置點的大小(Getting the Size of a Contact Point during Raw Touch)

POJ 2553 The Bottom of a Graph

har tac memset pac ack cpp namespace include string 我的第一道tarjin 要註意兩點,有向圖一定要判斷點是否在棧中 彈棧的時候不能判斷low[x]==low[stack[top]] #include <cstdi

poj 2553 The Bottom of a Graph (Tarjan強聯通)

題意:在v可以到達的所有點也都可以到達v,由此就可以知道求解縮點以後出度為0的點中的節點數字即可 思路:就是縮點後,輸出出度為0的點內的點。 #pragma GCC optimize(2) #include<stdio.h> #include<algorithm

The Benefits Of A Small Concrete Mixer Truck

Should you are employed in the construction industry, you are going to learn that a tiny concrete mixer truck will come in very handy. These truck

HDU 4028 The time of a day (dp+離散化)

題意:給你1~n的數字,問你一個集合中的lcm大於m的集合有多少個 思路:這個題挺有意思的,我們直接的可以想到爆枚的話的複雜度有2^40,但是這些數中的lcm的答案缺不會有很多,最多也就是這40個數的lcm,所以不會有很大,那這樣的話我們用一個map來記錄dp[i]代表當前是有前i個數,對於每i個數的map

PBRT_V2 總結記錄 Expected Value of the Function of a Random Variable

The Function of a Random Variable   F(X) is a transformed version of X. You should not assume that F(X) will have the same probability distri

TypeError: The value of a feed cannot be a tf.Tensor object.

在進行佔位符時   遇到這個問題   TypeError: The value of a feed cannot be a tf.Tensor object. Acceptable feed values include Python scalars, stri

"The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value

這句話的意思是將datetime2資料型別轉換為datetime資料型別會導致超出範圍的值。宣告已經終止。 在使用EF插入資料是發生列轉換的錯誤,搞了好久,不知道問題出在哪裡! 根據提示的錯誤資訊來看是Datetime資料型別出現錯誤 後來發現 public Nullable<S

Assignment代寫:The possibility of a financial crisis

下面為大家整理一篇優秀的assignment代寫範文- The possibility of a financial crisis,供大家參考學習,這篇論文討論了金融危機的可能性。金融危機的可能性既是潛在的可能性,又是現實的可能性,這兩種可能性都由經濟過程內在的

New Analyses May Imply 4g lte modem the Existence of a Dark Matter Particle

www.inhandnetworks.com Mysterious dark matter makes up approximately 26 percent of the mass of the universe. At a major UCLA symposium attended

[iOS] How to round the corners of a button

如何做出圓角的按鈕?比我想像中的簡單,其實一行指令(buyButton.layer.cornerRadius)就完成了。 實作出來的效果,我是用 cornerRadius = 5 You can manipulate the CALayer of your button to do this pre

Anatomy of a Program in Memory.剖析程序的內存布局

view 賦值 什麽 分享 應用程序 使用 ble 跟蹤 系統 原文標題:Anatomy of a Program in Memory 原文地址:http://duartes.org/gustavo/blog/ [註:本人水平有限,只好挑一些國外高手的精彩文章翻譯一下

The art of A/B testing

In particular, I will show:how the Z-test can be applied to testing whether the clients experiencing B spend more time on averagehow the χ² test can be use

The Anatomy of Charisma

This story is for Medium members.Continue with FacebookContinue with GoogleMedium curates expert stories from leading publishers exclusively for members (w