# Librerie utili
library("tidyverse")
library("lubridate")
library("scales")
library("janitor")
library("here")
library("ggrepel")
library("readxl")
library("tidytext")
# Libreria specifica per GA4
library("googleAnalyticsR")
# Working directory
setwd(here::here())
Google Analytics 4 API into R
Link Utili
Supporto R
https://8-bit-sheep.com/googleAnalyticsR/articles/reporting-ga4.html
https://rdrr.io/cran/googleAnalyticsR/man/ga_data_filter.html
Supporto GA4
https://ga-dev-tools.google/ga4/dimensions-metrics-explorer/
https://developers.google.com/analytics/devguides/reporting/data/v1/api-schema
Librerie
Autenticazione
Inserisco la mail collegata ad analytics.
ga_auth(email = "..." )
Proseguo l’autenticazione su Browser flaggando tutti i campi.
ga_account_list(type = "ga4")
<- ga_meta(propertyId = "...") metadati
Vedo la lista degli account a cui ho accesso e poi posso vedere metadati associati, tra cui il nome delle dimensioni/metriche presenti in una data property.
Set Up
Definisco alcune variabili per l’estrazione: property_id, from_date, to_date, ga4_dimensions, ga4_metrics.
Property ID
Scelgo la property da cui estrarre i dati.
= "property_id" #recuperato da ga_account_list() property_id
Date
Definisco range temporale che mi interessa.
<- "2023-09-12"
from_date <- "2023-09-19" to_date
Dimensioni
Seleziono le dimensioni che mi servono, scritte tra virgolette. Il nome API lo recupero o dai metadati oppure dalla pagina: https://developers.google.com/analytics/devguides/reporting/data/v1/api-schema?hl=it, contenente la lista delle dimensioni/metriche con descrizione.
<- c(
ga4_dimensions "date",
"month",
"sessionDefaultChannelGroup",
"eventName"
)
Metriche
Seleziono le dimensioni che mi servono, scritte tra virgolette. Il nome API lo recupero o dai metadati oppure dalla pagina: https://developers.google.com/analytics/devguides/reporting/data/v1/api-schema?hl=it, contenente la lista delle dimensioni/metriche con descrizione.
<- c(
ga4_metrics "sessions",
"eventCount",
"engagedSessions",
"bounceRate",
"averageSessionDuration",
"totalUsers"
)
Estrazione
La funzione ga_data() prende in input property_id, date_range, dimensions, metrics e gli passiamo le variabili definite prima e assegna all’oggetto df_ga4 il database estratto.
<- ga_data(
df_ga4 propertyId = property_id,
date_range = c(from_date, to_date),
dimensions = ga4_dimensions,
metrics = ga4_metrics
)
Filtri
Per creare un filtro si usa l’argomento dim_filter con la funzione ga_data_filter(). Per esempi su definizione di filtri vedere https://rdrr.io/cran/googleAnalyticsR/man/ga_data_filter.html.
<- ga_data(
df_ga4 propertyId = property_id,
date_range = c(from_date, to_date),
dimensions = ga4_dimensions,
metrics = ga4_metrics,
dim_filter = ga_data_filter(x)
)
map_dfr()
Nel caso in cui si volesse fare la stessa identica estrazione da più property e poi fare un append in un unico database si può usare la funzione map_dfr della libreria purrr dell’universo tidyverse.
<- ga_account_list(type = "ga4") %>%
df_accounts_ga4 ::clean_names() %>%
janitor::select(-account_id, -property_name)
dplyr
<- map_dfr(df_accounts_ga4$property_id,
df_ga4 function(property){
<- ga_data(property,
df_ga4 date_range = date_range,
metrics = ga4_metrics_ss,
dimensions = ga4_dimensions_ss,
limit = -1) %>%
::clean_names() %>%
janitoras_tibble()
return(df_ga4)
})
Prima creo il df contenente tutte le property da cui voglio estrarre con i rispettivi property_id, dopo assegno come argomento della funzione map_dfr il vettore delle property in modo da ciclare su ognuna di esse. In questo modo però non ho indicazione di come distinguere i dati delle property. Quindi posso aggiungere una colonna uguale al nome della property.
<- ga_account_list(type = "ga4") %>%
df_accounts_ga4 ::clean_names() %>%
janitor::select(-account_id, -property_name)
dplyr
<- map_dfr(df_accounts_ga4$property_id,
df_ga4 function(property){
<- ga_data(property,
df_ga4 date_range = date_range,
metrics = ga4_metrics_ss,
dimensions = ga4_dimensions_ss,
limit = -1) %>%
::clean_names() %>%
janitoras_tibble() %>%
mutate(account_name = df_accounts_ga4 %>%
filter(property_id == property) %>%
pull(account_name) %>%
first())
In questo caso creo una variabile di flag chiamata account_name che è uguale al nome della property GA4 da cui provengono i dati, utile a raggruppamenti o segmentazione dei dati.
DDP
Nel caso del DDP abbiamo una property unica per la combinazione brand-mercato. Quindi il numero di estrazioni è molto elevato, ma la struttura delle estrazioni è sempre la stessa.
set up
Definisco prima due vettori con la lista dei mercati e dei brand.
ga_auth(email = "l.bongiorno@reply.it" )
ga_account_list(type = "ga4")
# property dei brand
<- ga_account_list(type = "ga4") %>%
df_accounts_STLA ::clean_names() %>%
janitor::select(-account_id, -property_name) %>%
dplyrfilter(str_detect(account_name, "Fiat|Jeep|Alfa|Abarth|Lancia")) %>%
separate(col = "account_name",
into = c("brand", "market"),
sep = "\\|") %>%
mutate(brand = str_trim(brand),
market = str_trim(market)) %>%
# le properties di LU e BE per i mercati sotto danno errore
filter(!((market == "LU"|market == "BE") &
== "Jeep" | brand == "Lancia"))
(brand
# property della Splashpage
<- ga_account_list(type = "ga4") %>%
df_accounts_PSA ::clean_names() %>%
janitor::select(-account_id, -property_name) %>%
dplyrfilter(str_detect(account_name, "PSA")) %>%
separate(col = "account_name",
into = c("brand", "market"),
sep = "\\|") %>%
mutate(brand = str_trim(brand),
market = str_trim(market))
Il df_accounts_STLA contiene le property dei brand, mentre il df_accounts_PSA contiene la property specifica della Splashpage (unica per tutti i brand e tutti i mercati). Entrambi i df contengono la colonna brand, la colonna market (ricavate dal nome dell’account) e la property_id.
esempio singolo mercato
Per estrarre i dati di un singolo mercato, per tutti i brand si può usare questo codice.
# Seleziono il mercato che mi interessa, definendo variabile var_market
= "IT"
var_market
# creo df set up del mercato
<- df_accounts_STLA %>%
df_account_IT filter(market == var_market)
# estraggo dati
<- map_dfr(df_account_IT,
df_ga4_IT function(property){
<- ga_data(property,
df_ga4 date_range = date_range,
metrics = ga4_metrics,
dimensions = ga4_dimensions,
dim_filters = ga_data_filter("customEvent:site_type" == "dealer website" ),
limit = -1) %>%
::clean_names() %>%
janitoras_tibble() %>%
mutate(market = df_account_IT %>%
filter(property_id == property) %>%
pull(market) %>%
first())
mutate(market = df_account_IT %>%
filter(property_id == property) %>%
pull(market) %>%
first(),
brand = df_account_IT %>%
filter(property_id == property) %>%
pull(brand) %>%
first()
)
return(df_ga4)
})
Uso la funzione ga_data_filter per assicurarci di estrarre solo i dati dei DWS e non dei siti di brand.
esempio calcolo KPI per mese
Normalizzo la data, raggruppo per mese e sommo i KPI di interesse.
%>%
df_ga4_IT mutate(dt = floor_date(date, unit = "months")) %>%
group_by(dt) %>%
summarise(sessions = sum(sessions),
engaged = sum(engaged_sessions),
bounce_rate = mean(bounce_rate),
duration = mean(average_session_duration))
esempio calcolo site sections
Voglio avere il traffico per sezione del sito, quindi estraggo come metrica le sessions e la dimensione custom customEvent:site_typelevel2.
<- c("sessions")
ga4_metrics_ss <- c("date", "customEvent:site_type", "customEvent:site_typelevel2") ga4_dimensions_ss
Replico la stessa estrazione aggiornando dimensioni e metriche di interesse.
<- map_dfr(df_account_IT$property_id,
df_ss_IT function(property){
<- ga_data(property,
df_ga4 date_range = date_range,
metrics = ga4_metrics_ss,
dimensions = ga4_dimensions_ss,
dim_filters = ga_data_filter("customEvent:site_type" == "dealer website" ),
limit = -1) %>%
::clean_names() %>%
janitoras_tibble() %>%
mutate(market = df_account_IT %>%
filter(property_id == property) %>%
pull(market) %>%
first())
mutate(market = df_account_IT %>%
filter(property_id == property) %>%
pull(market) %>%
first(),
brand = df_account_IT %>%
filter(property_id == property) %>%
pull(brand) %>%
first()
)
return(df_ga4)
%>%
}) mutate(site_section = case_when(
str_detect(custom_event_site_typelevel2, "ownership:") ~ "aftersales",
str_detect(custom_event_site_typelevel2, "about-us|offices") ~ "about us",
str_detect(custom_event_site_typelevel2, "showroom$") ~ "showroom_hub",
str_detect(custom_event_site_typelevel2, "showroom:") ~ "showroom_detail",
str_detect(custom_event_site_typelevel2, "used-inventory$") ~ "used_inventory_hub",
str_detect(custom_event_site_typelevel2, "promotions$") ~ "promo_hub",
str_detect(custom_event_site_typelevel2, "homepage") ~ "homepage",
str_detect(custom_event_site_typelevel2, "promotions:") ~ "promo_detail",
TRUE ~ "other"
))
Dopo calcolo la somma di sessions per site sections.
%>%
df_ss_AT mutate(dt = floor_date(date, unit = "months")) %>%
group_by(dt, site_section) %>%
summarise(sessions = sum(sessions))
append
Creo una funzione per replicare l’estrazione e applicarla a mercati e report suite diverse. Come argomenti devo passargli il df della report suite, il vettore di metriche e il vettore di dimensioni.
<- function(df_account, ga4_metrics, ga4_dimensions){
fn_ga4_extraction map_dfr(df_account,
function(property){
<- ga_data(property,
df_ga4 date_range = date_range,
metrics = ga4_metrics,
dimensions = ga4_dimensions,
dim_filters = ga_data_filter("customEvent:site_type" == "dealer website" ),
limit = -1) %>%
::clean_names() %>%
janitoras_tibble() %>%
mutate(market = df_account %>%
filter(property_id == property) %>%
pull(market) %>%
first())
mutate(market = df_account %>%
filter(property_id == property) %>%
pull(market) %>%
first(),
brand = df_account %>%
filter(property_id == property) %>%
pull(brand) %>%
first()
)
return(df_ga4)
}) }
Dopo eseguo la funzione per i mercati in scope.
<- fn_ga4_extraction(df_account_IT, ga4_metrics_IT, ga4_dimensions_IT)
df_ga4_IT <- fn_ga4_extraction(df_account_DE, ga4_metrics_DE, ga4_dimensions_DE)
df_ga4_DE <- fn_ga4_extraction(df_account_BE, ga4_metrics_BE, ga4_dimensions_BE)
df_ga4_BE <- fn_ga4_extraction(df_account_LU, ga4_metrics_LU, ga4_dimensions_LU)
df_ga4_LU <- fn_ga4_extraction(df_account_AT, ga4_metrics_AT, ga4_dimensions_AT)
df_ga4_AT <- fn_ga4_extraction(df_account_PT, ga4_metrics_PT, ga4_dimensions_PT) df_ga4_PT
A questo punto creo un unico dataframe contenente tutti i dati.
splashpage
Per i dati della splashpage devo estrarre dalla property specifica PSA, filtrando sempre il site type ed eventualmente il mercato.
<- c("date", "customEvent:site_type", "customEvent:site_country")
ga4_dimensions_splash
<- ga_data(df_accounts_PSA$property_id,
df_splash date_range = date_range,
metrics = ga4_metrics,
dimensions = ga4_dimensions_splash,
limit = -1) %>%
::clean_names() %>%
janitoras_tibble()
%>%
df_splash filter(custom_event_site_type == "dealer website",
== "it") %>%
custom_event_site_country mutate(dt = floor_date(date, unit = "months")) %>%
group_by(dt) %>%
summarise(sessions = sum(sessions),
engaged = sum(engaged_sessions),
bounce_rate = mean(bounce_rate))
In questo modo estraggo i KPI relativi al traffico, raggruppo per mese e sommo.
<- ga_data(df_accounts_PSA$property_id,
df_splash_events date_range = date_range,
metrics = "eventCount",
dimensions = c("date",
"customEvent:site_country",
"customEvent:asset_owner",
"eventName"),
limit = -1) %>%
::clean_names() %>%
janitoras_tibble()
%>%
df_splash_events filter(custom_event_asset_owner == "dealer",
== "it",
custom_event_site_country str_detect(event_name, "form")) %>%
mutate(dt = floor_date(date, unit = "months")) %>%
group_by(dt) %>%
summarise(count = sum(event_count))
In questo modo estraggo il conteggio di eventi, raggruppo per mese e sommo. Filtro il nome dell’evento di interesse dalla dimensione event_name.
Salvo dati estratti in Excel
Mi assicuro di aver definito la working directory in cui vado a salvare il file Excel con i dati estratti.
install.packages("openxlsx")
library("openxlsx")
# Crea un nuovo libro di lavoro
<- createWorkbook()
wb # Aggiunge un foglio di lavoro al libro
addWorksheet(wb, "nome_del_foglio_excel")
# Scrive i dati nei fogli di lavoro
writeData(wb, "nome_del_foglio_excel", df_ga4)
# Salva il libro di lavoro
saveWorkbook(wb, "nome_del_file_excel.xlsx")
Codice DDP PRONTO DA USARE
# Librerie utili
library("tidyverse")
library("lubridate")
library("scales")
library("janitor")
library("here")
library("ggrepel")
library("readxl")
library("tidytext")
# Libreria specifica per GA4
library("googleAnalyticsR")
# Working directory
setwd(here::here())
# Authentication
ga_auth(email = "l.bongiorno@reply.it" )
# property dei brand
<- ga_account_list(type = "ga4") %>%
df_accounts_STLA ::clean_names() %>%
janitor::select(-account_id, -property_name) %>%
dplyrfilter(str_detect(account_name, "Fiat|Jeep|Alfa|Abarth|Lancia")) %>%
separate(col = "account_name",
into = c("brand", "market"),
sep = "\\|") %>%
mutate(brand = str_trim(brand),
market = str_trim(market)) %>%
# le properties di LU e BE per i mercati sotto danno errore
filter(!((market == "LU"|market == "BE") &
== "Jeep" | brand == "Lancia"))
(brand
# property della Splashpage
<- ga_account_list(type = "ga4") %>%
df_accounts_PSA ::clean_names() %>%
janitor::select(-account_id, -property_name) %>%
dplyrfilter(str_detect(account_name, "PSA")) %>%
separate(col = "account_name",
into = c("brand", "market"),
sep = "\\|") %>%
mutate(brand = str_trim(brand),
market = str_trim(market))
# creo df set up del mercato
<- df_accounts_STLA %>% filter(market == "IT")
df_account_IT <- df_accounts_STLA %>% filter(market == "DE")
df_account_DE <- df_accounts_STLA %>% filter(market == "BE")
df_account_BE <- df_accounts_STLA %>% filter(market == "LU")
df_account_LU <- df_accounts_STLA %>% filter(market == "AT")
df_account_AT <- df_accounts_STLA %>% filter(market == "PT")
df_account_PT
# funzione estrazione
<- function(df_account, ga4_metrics, ga4_dimensions){
fn_ga4_extraction map_dfr(df_account,
function(property){
<- ga_data(property,
df_ga4 date_range = date_range,
metrics = ga4_metrics,
dimensions = ga4_dimensions,
dim_filters = ga_data_filter("customEvent:site_type" == "dealer website" ),
limit = -1) %>%
::clean_names() %>%
janitoras_tibble() %>%
mutate(market = df_account %>%
filter(property_id == property) %>%
pull(market) %>%
first())
mutate(market = df_account %>%
filter(property_id == property) %>%
pull(market) %>%
first(),
brand = df_account %>%
filter(property_id == property) %>%
pull(brand) %>%
first()
)
return(df_ga4)
})
}
<- c("2024-10-31", "2025-02-28")
date_range <- "sessions"
ga4_metrics <- c("date", "month")
ga4_dimensions
<- fn_ga4_extraction(df_account_IT, ga4_metrics, ga4_dimensions)
df_ga4_IT <- fn_ga4_extraction(df_account_DE, ga4_metrics, ga4_dimensions)
df_ga4_DE <- fn_ga4_extraction(df_account_BE, ga4_metrics, ga4_dimensions)
df_ga4_BE <- fn_ga4_extraction(df_account_LU, ga4_metrics, ga4_dimensions)
df_ga4_LU <- fn_ga4_extraction(df_account_AT, ga4_metrics, ga4_dimensions)
df_ga4_AT <- fn_ga4_extraction(df_account_PT, ga4_metrics, ga4_dimensions)
df_ga4_PT
<- rbind(df_ga4_IT, df_ga4_DE, df_ga4_BE, df_ga4_LU, df_ga4_AT, df_ga4_PT)
df_ga4_finale
<- createWorkbook()
wb addWorksheet(wb, "GA4 data")
writeData(wb, "GA4 data", df_ga4_finale)
saveWorkbook(wb, "GA4_DATA_BRAND.xlsx")
Poi estraggo i dati della Splashpage.
<- c("date", "customEvent:site_country"))
ga4_dimensions_splash
<- ga_data(df_accounts_PSA$property_id,
df_splash date_range = date_range,
metrics = ga4_metrics,
dimensions = ga4_dimensions_splash,
dim_filters = ga_data_filter("customEvent:site_type" == "dealer website" ),
limit = -1) %>%
::clean_names() %>%
janitoras_tibble()
<- createWorkbook()
wb2 addWorksheet(wb2, "GA4 data Splash")
writeData(wb2, "GA4 data Splash", df_splash)
saveWorkbook(wb2, "GA4_DATA_SPLASH.xlsx")