Voice Search Strategy & Optimization for SEO

When’s the last time you thought about voice search strategy & optimization for SEO? At the time of writing this (summer 2021) everyone I know (myself included) are pretty occupied with Core Web Vitals and Page Experience rolling out, alongside other algo updates. (See also: Google Traffic Down!) But it’s refreshing to spend some time […]

When’s the last time you thought about voice search strategy & optimization for SEO? At the time of writing this (summer 2021) everyone I know (myself included) are pretty occupied with Core Web Vitals and Page Experience rolling out, alongside other algo updates. (See also: Google Traffic Down!)

But it’s refreshing to spend some time thinking about the future, or at least long tail search. 🙂

I saw an interesting post yesterday on voice search optimization and SEO on LinkedIn. Some folks found really good use of the newfound Regex functionality in Google Search Console to use a bunch of OR statements to get data on conversational keywords.

Only one problem for the seasoned optimization pro. It does nothing for problems of scale. Looking to get more than a few hundred keywords at a time? Out of luck. Looking for keywords by page? Unlikely to happen quickly.

There are even tons of resources out there, dicing voice search strategy and optimization 27 ways to Sunday. If Brian Dean is out writing a guide on it, you have to know there’s interest for it! But again, a lot of the most visible material gives a lot of basic insight, and then non-scalable instructions on pulling conversational keywords out of Search Console. How can we do better?

Solving for Scale in Voice Search Strategy & Optimization for SEO

What’s an enterprise digital marketer and SEO to do? Sounds like it’s time to revisit our post on how to download from Google Search Console & export all your data! More specifically, if you need scale, that means automation, and automation means rolling up your coding sleeves. 🙂

# Load packages #
library(searchConsoleR)
library(dplyr)
library(ggplot2)
library(writexl)
library(stringr)

# Authorize & choose Google profile #
scr_auth()

# Specify website --- Client Code or Line of Business Code Here #
client <- "CLCODE"
website <- "https://www.twosigma.com"

############ SPECIFYING THE MONTHS ############
start1 <- "2020-04-01"
end1 <- "2020-04-30"

start2 <- "2020-05-01"
end2 <- "2020-05-31"

start3 <- "2020-06-01"
end3 <- "2020-06-30"

start4 <- "2020-07-01"
end4 <- "2020-07-31"

start5 <- "2020-08-01"
end5 <- "2020-08-31"

start6 <- "2020-09-01"
end6 <- "2020-09-30"

start7 <- "2020-10-01"
end7 <- "2020-10-31"

start8 <- "2020-11-01"
end8 <- "2020-11-30"

start9 <- "2020-12-01"
end9 <- "2020-12-31"

start10 <- "2021-01-01"
end10 <- "2021-01-31"

start12 <- "2021-02-01"
end12 <- "2021-02-28"

start13 <- "2021-03-01"
end13 <- "2021-03-31"

start14 <- "2021-04-01"
end14 <- "2021-04-30"

start15 <- "2021-05-01"
end15 <- "2021-05-31"

start16 <- "2021-06-01"
end16 <- "2021-06-30"

# Specify the voice cue variables for dataframe functionality #
who <- "who" # 1
what <- "what" # 1
when <- "when" # 1
where <- "where" # 1
why <- "why" # 1
how  <-  "how" # 1
does <- "does" # 1
have <- "have" # 1
has <- "has" # 1
are <- "are" # 1
which <- "which" # 1
will <- "will" # 1
was <- "was" # 1
should <- "should" # 1
would <- "would" # 1
could <- "could" # 1
near <- "near" # 1
google <- "google" # 1 
alexa <- "alexa" # 1 
do <- "do" # 1
is <- "is" # 1
can <- "can" # 1


# #
# #            _____
# # |\    /|  |     |     1
# # | \  / |  |     |
# # |  \/  |  |     |
# # |      |  |     |
# # |      |  |     |
# # |      |  |     |
# # |      |  |_____|
# #
# #


# # # Start who 1
# # #
# # #
# # #
# # #

############ REPLACE QUERY  ############
who_queries <- search_analytics(
                   siteURL = website, 
                   startDate = start1,
                   endDate = end1,
                   dimensions = c("query", "page"),
     ##### REPLACE QUERY #####
                   dimensionFilterExp = c("query~~who"),
                   searchType="web",
                   rowLimit = 1000000
                   )

# Dynamically get the number of rows from the GSC export so the created vectors match number of rows
############ REPLACE QUERY  ############
rows <- nrow(who_queries)
# Testing purposes - making sure rows vector was properly formed
# rows

# Make a vector that populates the client code
clientName <- rep(client,rows)
# Testing vector creation
# clientName

# Make a vector that populates the start date for Month filtering, segmenting, pivoting
########                       ########
############ REPLACE DATE  ############
date <- rep(start1,rows)
# Testing vector creation
# date

############ REPLACE QUERY  ############
primaryCue <- rep(who,rows)
# primaryCue

# Make a data frame from the created vectors
who_queries_merged_1 <- data.frame(clientName,date,primaryCue,who_queries)
# Testing df creation
# pivotData
# head(who_queries_merged_1,5)

############### QA CHECKPOINT ######################
# Write the data frame to an XLSX file
# write_xlsx(who_queries_merged, "who_queries_1.xlsx")

# # # END who 1
# # #
# # #
# # #
# # #


# # # Start what 1
# # #
# # #
# # #
# # #

############ REPLACE QUERY  ############
what_queries <- search_analytics(
                   siteURL = website, 
                   startDate = start1,
                   endDate = end1,
                   dimensions = c("query", "page"),
     ##### REPLACE QUERY #####
                   dimensionFilterExp = c("query~~what"),
                   searchType="web",
                   rowLimit = 1000000
                   )

# Dynamically get the number of rows from the GSC export so the created vectors match number of rows
############ REPLACE QUERY  ############
rows <- nrow(what_queries)
# Testing purposes - making sure rows vector was properly formed
# rows

# Make a vector that populates the client code
clientName <- rep(client,rows)
# Testing vector creation
# clientName

# Make a vector that populates the start date for Month filtering, segmenting, pivoting
########                       ########
############ REPLACE DATE  ############
date <- rep(start1,rows)
# Testing vector creation
# date

############ REPLACE QUERY  ############
primaryCue <- rep(what,rows)
# primaryCue

# Make a data frame from the created vectors
what_queries_merged_1 <- data.frame(clientName,date,primaryCue,what_queries)
# Testing df creation
# pivotData
# head(what_queries_merged_1,5)

############### QA CHECKPOINT ######################
# Write the data frame to an XLSX file
# write_xlsx(what_queries_merged, "what_queries_1.xlsx")

# # # END what 1
# # #
# # #
# # #
# # #


# # # Start when 1
# # #
# # #
# # #
# # #

############ REPLACE QUERY  ############
when_queries <- search_analytics(
                   siteURL = website, 
                   startDate = start1,
                   endDate = end1,
                   dimensions = c("query", "page"),
     ##### REPLACE QUERY #####
                   dimensionFilterExp = c("query~~when"),
                   searchType="web",
                   rowLimit = 1000000
                   )

# Dynamically get the number of rows from the GSC export so the created vectors match number of rows
############ REPLACE QUERY  ############
rows <- nrow(when_queries)
# Testing purposes - making sure rows vector was properly formed
# rows

# Make a vector that populates the client code
clientName <- rep(client,rows)
# Testing vector creation
# clientName

# Make a vector that populates the start date for Month filtering, segmenting, pivoting
########                       ########
############ REPLACE DATE  ############
date <- rep(start1,rows)
# Testing vector creation
# date

############ REPLACE QUERY  ############
primaryCue <- rep(when,rows)
# primaryCue

# Make a data frame from the created vectors
when_queries_merged_1 <- data.frame(clientName,date,primaryCue,when_queries)
# Testing df creation
# pivotData
# head(when_queries_merged_1,5)

############### QA CHECKPOINT ######################
# Write the data frame to an XLSX file
# write_xlsx(when_queries_merged, "when_queries_1.xlsx")

# # # END when 1
# # #
# # #
# # #
# # #


# # # Start where 1
# # #
# # #
# # #
# # #

############ REPLACE QUERY  ############
where_queries <- search_analytics(
                   siteURL = website, 
                   startDate = start1,
                   endDate = end1,
                   dimensions = c("query", "page"),
     ##### REPLACE QUERY #####
                   dimensionFilterExp = c("query~~where"),
                   searchType="web",
                   rowLimit = 1000000
                   )

# Dynamically get the number of rows from the GSC export so the created vectors match number of rows
############ REPLACE QUERY  ############
rows <- nrow(where_queries)
# Testing purposes - making sure rows vector was properly formed
# rows

# Make a vector that populates the client code
clientName <- rep(client,rows)
# Testing vector creation
# clientName

# Make a vector that populates the start date for Month filtering, segmenting, pivoting
########                       ########
############ REPLACE DATE  ############
date <- rep(start1,rows)
# Testing vector creation
# date

############ REPLACE QUERY  ############
primaryCue <- rep(where,rows)
# primaryCue

# Make a data frame from the created vectors
where_queries_merged_1 <- data.frame(clientName,date,primaryCue,where_queries)
# Testing df creation
# pivotData
# head(where_queries_merged_1,5)

############### QA CHECKPOINT ######################
# Write the data frame to an XLSX file
# write_xlsx(where_queries_merged, "where_queries_1.xlsx")

# # # END where 1
# # #
# # #
# # #
# # #


# # # Start why 1
# # #
# # #
# # #
# # #

############ REPLACE QUERY  ############
why_queries <- search_analytics(
                   siteURL = website, 
                   startDate = start1,
                   endDate = end1,
                   dimensions = c("query", "page"),
     ##### REPLACE QUERY #####
                   dimensionFilterExp = c("query~~why"),
                   searchType="web",
                   rowLimit = 1000000
                   )

# Dynamically get the number of rows from the GSC export so the created vectors match number of rows
############ REPLACE QUERY  ############
rows <- nrow(why_queries)
# Testing purposes - making sure rows vector was properly formed
# rows

# Make a vector that populates the client code
clientName <- rep(client,rows)
# Testing vector creation
# clientName

# Make a vector that populates the start date for Month filtering, segmenting, pivoting
########                       ########
############ REPLACE DATE  ############
date <- rep(start1,rows)
# Testing vector creation
# date

############ REPLACE QUERY  ############
primaryCue <- rep(why,rows)
# primaryCue

# Make a data frame from the created vectors
why_queries_merged_1 <- data.frame(clientName,date,primaryCue,why_queries)
# Testing df creation
# pivotData
# head(why_queries_merged_1,5)

############### QA CHECKPOINT ######################
# Write the data frame to an XLSX file
# write_xlsx(why_queries_merged, "why_queries_1.xlsx")

# # # END why 1
# # #
# # #
# # #
# # #


# # # Start how 1
# # #
# # #
# # #
# # #

############ REPLACE QUERY  ############
how_queries <- search_analytics(
                   siteURL = website, 
                   startDate = start1,
                   endDate = end1,
                   dimensions = c("query", "page"),
     ##### REPLACE QUERY #####
                   dimensionFilterExp = c("query~~how"),
                   searchType="web",
                   rowLimit = 1000000
                   )

# Dynamically get the number of rows from the GSC export so the created vectors match number of rows
############ REPLACE QUERY  ############
rows <- nrow(how_queries)
# Testing purposes - making sure rows vector was properly formed
# rows

# Make a vector that populates the client code
clientName <- rep(client,rows)
# Testing vector creation
# clientName

# Make a vector that populates the start date for Month filtering, segmenting, pivoting
########                       ########
############ REPLACE DATE  ############
date <- rep(start1,rows)
# Testing vector creation
# date

############ REPLACE QUERY  ############
primaryCue <- rep(how,rows)
# primaryCue

# Make a data frame from the created vectors
how_queries_merged_1 <- data.frame(clientName,date,primaryCue,how_queries)
# Testing df creation
# pivotData
# head(how_queries_merged_1,5)

############### QA CHECKPOINT ######################
# Write the data frame to an XLSX file
# write_xlsx(how_queries_merged, "how_queries_1.xlsx")

# # # END how 1
# # #
# # #
# # #
# # #


# # # Start Does 1
# # #
# # #
# # #
# # #

############ REPLACE QUERY  ############
does_queries <- search_analytics(
                   siteURL = website, 
                   startDate = start1,
                   endDate = end1,
                   dimensions = c("query", "page"),
     ##### REPLACE QUERY #####
                   dimensionFilterExp = c("query~~does"),
                   searchType="web",
                   rowLimit = 1000000
                   )

# Dynamically get the number of rows from the GSC export so the created vectors match number of rows
############ REPLACE QUERY  ############
rows <- nrow(does_queries)
# Testing purposes - making sure rows vector was properly formed
# rows

# Make a vector that populates the client code
clientName <- rep(client,rows)
# Testing vector creation
# clientName

# Make a vector that populates the start date for Month filtering, segmenting, pivoting
########                       ########
############ REPLACE DATE  ############
date <- rep(start1,rows)
# Testing vector creation
# date

############ REPLACE QUERY  ############
primaryCue <- rep(does,rows)
# primaryCue

# Make a data frame from the created vectors
does_queries_merged_1 <- data.frame(clientName,date,primaryCue,does_queries)
# Testing df creation
# pivotData
# head(does_queries_merged_1,5)

############### QA CHECKPOINT ######################
# Write the data frame to an XLSX file
# write_xlsx(does_queries_merged, "does_queries_1.xlsx")

# # # END DOES 1
# # #
# # #
# # #
# # #


# # # Start Have 1
# # #
# # #
# # #
# # #

############ REPLACE QUERY  ############
have_queries <- search_analytics(
  siteURL = website, 
  startDate = start1,
  endDate = end1,
  dimensions = c("query", "page"),
  ##### REPLACE QUERY #####
  dimensionFilterExp = c("query~~have"),
  searchType="web",
  rowLimit = 1000000
)

# Dynamically get the number of rows from the GSC export so the created vectors match number of rows
############ REPLACE QUERY  ############
rows <- nrow(have_queries)
# Testing purposes - making sure rows vector was properly formed
# rows

# Make a vector that populates the client code
clientName <- rep(client,rows)
# Testing vector creation
# clientName

# Make a vector that populates the start date for Month filtering, segmenting, pivoting
########                       ########
############ REPLACE DATE  ############
date <- rep(start1,rows)
# Testing vector creation
# date

############ REPLACE QUERY  ############
primaryCue <- rep(have,rows)
# primaryCue

# Make a data frame from the created vectors
############ REPLACE QUERY  ############
have_queries_merged_1 <- data.frame(clientName,date,primaryCue,have_queries)
# Testing df creation
# pivotData
############ REPLACE QUERY  ############
# head(have_queries_merged_1,5)

############### QA CHECKPOINT ######################
# Write the data frame to an XLSX file
############ REPLACE QUERY  ############
# write_xlsx(have_queries_merged_1, "have_queries_1.xlsx")

# # # END HAVE 1
# # #
# # #
# # #
# # #


# # # Start has 1
# # #
# # #
# # #
# # #

############ REPLACE QUERY  ############
has_queries <- search_analytics(
  siteURL = website, 
  startDate = start1,
  endDate = end1,
  dimensions = c("query", "page"),
  ##### REPLACE QUERY #####
  dimensionFilterExp = c("query~~has"),
  searchType="web",
  rowLimit = 1000000
)

# Dynamically get the number of rows from the GSC export so the created vectors match number of rows
############ REPLACE QUERY  ############
rows <- nrow(has_queries)
# Testing purposes - making sure rows vector was properly formed
# rows

# Make a vector that populates the client code
clientName <- rep(client,rows)
# Testing vector creation
# clientName

# Make a vector that populates the start date for Month filtering, segmenting, pivoting
########                       ########
############ REPLACE DATE  ############
date <- rep(start1,rows)
# Testing vector creation
# date

############ REPLACE QUERY  ############
primaryCue <- rep(has,rows)
# primaryCue

# Make a data frame from the created vectors
############ REPLACE QUERY  ############
has_queries_merged_1 <- data.frame(clientName,date,primaryCue,has_queries)
# Testing df creation
# pivotData
############ REPLACE QUERY  ############
# head(has_queries_merged_1,5)

############### QA CHECKPOINT ######################
# Write the data frame to an XLSX file
############ REPLACE QUERY  ############
# write_xlsx(has_queries_merged_1, "has_queries_1.xlsx")

# # # END has 1
# # #
# # #
# # #
# # #


# # # Start Are 1
# # #
# # #
# # #
# # #

############ REPLACE QUERY  ############
are_queries <- search_analytics(
  siteURL = website, 
  startDate = start1,
  endDate = end1,
  dimensions = c("query", "page"),
  ##### REPLACE QUERY #####
  dimensionFilterExp = c("query~~are"),
  searchType="web",
  rowLimit = 1000000
)

# Dynamically get the number of rows from the GSC export so the created vectors match number of rows
############ REPLACE QUERY  ############
rows <- nrow(are_queries)
# Testing purposes - making sure rows vector was properly formed
# rows

# Make a vector that populates the client code
clientName <- rep(client,rows)
# Testing vector creation
# clientName

# Make a vector that populates the start date for Month filtering, segmenting, pivoting
########                       ########
############ REPLACE DATE  ############
date <- rep(start1,rows)
# Testing vector creation
# date

############ REPLACE QUERY  ############
primaryCue <- rep(are,rows)
# primaryCue

# Make a data frame from the created vectors
############ REPLACE QUERY  ############
are_queries_merged_1 <- data.frame(clientName,date,primaryCue,are_queries)
# Testing df creation
# pivotData
############ REPLACE QUERY  ############
# head(are_queries_merged_1,5)

############### QA CHECKPOINT ######################
# Write the data frame to an XLSX file
############ REPLACE QUERY  ############
# write_xlsx(are_queries_merged_1, "are_queries_1.xlsx")

# # # END ARE 1
# # #
# # #
# # #
# # #


# # # Start Which 1
# # #
# # #
# # #
# # #

############ REPLACE QUERY  ############
which_queries <- search_analytics(
  siteURL = website, 
  startDate = start1,
  endDate = end1,
  dimensions = c("query", "page"),
  ##### REPLACE QUERY #####
  dimensionFilterExp = c("query~~which"),
  searchType="web",
  rowLimit = 1000000
)

# Dynamically get the number of rows from the GSC export so the created vectors match number of rows
############ REPLACE QUERY  ############
rows <- nrow(which_queries)
# Testing purposes - making sure rows vector was properly formed
# rows

# Make a vector that populates the client code
clientName <- rep(client,rows)
# Testing vector creation
# clientName

# Make a vector that populates the start date for Month filtering, segmenting, pivoting
########                       ########
############ REPLACE DATE  ############
date <- rep(start1,rows)
# Testing vector creation
# date

############ REPLACE QUERY  ############
primaryCue <- rep(which,rows)
# primaryCue

# Make a data frame from the created vectors
############ REPLACE QUERY  ############
which_queries_merged_1 <- data.frame(clientName,date,primaryCue,which_queries)
# Testing df creation
# pivotData
############ REPLACE QUERY  ############
# head(which_queries_merged_1,5)

############### QA CHECKPOINT ######################
# Write the data frame to an XLSX file
############ REPLACE QUERY  ############
# write_xlsx(which_queries_merged_1, "which_queries_1.xlsx")

# # # END WHICH 1
# # #
# # #
# # #
# # #


# # # Start Will 1
# # #
# # #
# # #
# # #

############ REPLACE QUERY  ############
will_queries <- search_analytics(
  siteURL = website, 
  startDate = start1,
  endDate = end1,
  dimensions = c("query", "page"),
  ##### REPLACE QUERY #####
  dimensionFilterExp = c("query~~will"),
  searchType="web",
  rowLimit = 1000000
)

# Dynamically get the number of rows from the GSC export so the created vectors match number of rows
############ REPLACE QUERY  ############
rows <- nrow(will_queries)
# Testing purposes - making sure rows vector was properly formed
# rows

# Make a vector that populates the client code
clientName <- rep(client,rows)
# Testing vector creation
# clientName

# Make a vector that populates the start date for Month filtering, segmenting, pivoting
########                       ########
############ REPLACE DATE  ############
date <- rep(start1,rows)
# Testing vector creation
# date

############ REPLACE QUERY  ############
primaryCue <- rep(will,rows)
# primaryCue

# Make a data frame from the created vectors
############ REPLACE QUERY  ############
will_queries_merged_1 <- data.frame(clientName,date,primaryCue,will_queries)
# Testing df creation
# pivotData
############ REPLACE QUERY  ############
# head(will_queries_merged_1,5)

############### QA CHECKPOINT ######################
# Write the data frame to an XLSX file
############ REPLACE QUERY  ############
# write_xlsx(will_queries_merged_1, "will_queries_1.xlsx")

# # # END will 1
# # #
# # #
# # #
# # #


# # # Start was 1
# # #
# # #
# # #
# # #

############ REPLACE QUERY  ############
was_queries <- search_analytics(
  siteURL = website, 
  startDate = start1,
  endDate = end1,
  dimensions = c("query", "page"),
  ##### REPLACE QUERY #####
  dimensionFilterExp = c("query~~was"),
  searchType="web",
  rowLimit = 1000000
)

# Dynamically get the number of rows from the GSC export so the created vectors match number of rows
############ REPLACE QUERY  ############
rows <- nrow(was_queries)
# Testing purposes - making sure rows vector was properly formed
# rows

# Make a vector that populates the client code
clientName <- rep(client,rows)
# Testing vector creation
# clientName

# Make a vector that populates the start date for Month filtering, segmenting, pivoting
########                       ########
############ REPLACE DATE  ############
date <- rep(start1,rows)
# Testing vector creation
# date

############ REPLACE QUERY  ############
primaryCue <- rep(was,rows)
# primaryCue

# Make a data frame from the created vectors
############ REPLACE QUERY  ############
was_queries_merged_1 <- data.frame(clientName,date,primaryCue,was_queries)
# Testing df creation
# pivotData
############ REPLACE QUERY  ############
# head(was_queries_merged_1,5)

############### QA CHECKPOINT ######################
# Write the data frame to an XLSX file
############ REPLACE QUERY  ############
# write_xlsx(was_queries_merged_1, "was_queries_1.xlsx")

# # # END was 1
# # #
# # #
# # #
# # #


# # # Start should 1
# # #
# # #
# # #
# # #

############ REPLACE QUERY  ############
should_queries <- search_analytics(
  siteURL = website, 
  startDate = start1,
  endDate = end1,
  dimensions = c("query", "page"),
  ##### REPLACE QUERY #####
  dimensionFilterExp = c("query~~should"),
  searchType="web",
  rowLimit = 1000000
)

# Dynamically get the number of rows from the GSC export so the created vectors match number of rows
############ REPLACE QUERY  ############
rows <- nrow(should_queries)
# Testing purposes - making sure rows vector should properly formed
# rows

# Make a vector that populates the client code
clientName <- rep(client,rows)
# Testing vector creation
# clientName

# Make a vector that populates the start date for Month filtering, segmenting, pivoting
########                       ########
############ REPLACE DATE  ############
date <- rep(start1,rows)
# Testing vector creation
# date

############ REPLACE QUERY  ############
primaryCue <- rep(should,rows)
# primaryCue

# Make a data frame from the created vectors
############ REPLACE QUERY  ############
should_queries_merged_1 <- data.frame(clientName,date,primaryCue,should_queries)
# Testing df creation
# pivotData
############ REPLACE QUERY  ############
# head(should_queries_merged_1,5)

############### QA CHECKPOINT ######################
# Write the data frame to an XLSX file
############ REPLACE QUERY  ############
# write_xlsx(should_queries_merged_1, "should_queries_1.xlsx")

# # # END should 1
# # #
# # #
# # #
# # #


# # # Start would 1
# # #
# # #
# # #
# # #

############ REPLACE QUERY  ############
would_queries <- search_analytics(
  siteURL = website, 
  startDate = start1,
  endDate = end1,
  dimensions = c("query", "page"),
  ##### REPLACE QUERY #####
  dimensionFilterExp = c("query~~would"),
  searchType="web",
  rowLimit = 1000000
)

# Dynamically get the number of rows from the GSC export so the created vectors match number of rows
############ REPLACE QUERY  ############
rows <- nrow(would_queries)
# Testing purposes - making sure rows vector would properly formed
# rows

# Make a vector that populates the client code
clientName <- rep(client,rows)
# Testing vector creation
# clientName

# Make a vector that populates the start date for Month filtering, segmenting, pivoting
########                       ########
############ REPLACE DATE  ############
date <- rep(start1,rows)
# Testing vector creation
# date

############ REPLACE QUERY  ############
primaryCue <- rep(would,rows)
# primaryCue

# Make a data frame from the created vectors
############ REPLACE QUERY  ############
would_queries_merged_1 <- data.frame(clientName,date,primaryCue,would_queries)
# Testing df creation
# pivotData
############ REPLACE QUERY  ############
# head(would_queries_merged_1,5)

############### QA CHECKPOINT ######################
# Write the data frame to an XLSX file
############ REPLACE QUERY  ############
# write_xlsx(would_queries_merged_1, "would_queries_1.xlsx")

# # # END would 1
# # #
# # #
# # #
# # #


# # # Start could 1
# # #
# # #
# # #
# # #

############ REPLACE QUERY  ############
could_queries <- search_analytics(
  siteURL = website, 
  startDate = start1,
  endDate = end1,
  dimensions = c("query", "page"),
  ##### REPLACE QUERY #####
  dimensionFilterExp = c("query~~could"),
  searchType="web",
  rowLimit = 1000000
)

# Dynamically get the number of rows from the GSC export so the created vectors match number of rows
############ REPLACE QUERY  ############
rows <- nrow(could_queries)
# Testing purposes - making sure rows vector could properly formed
# rows

# Make a vector that populates the client code
clientName <- rep(client,rows)
# Testing vector creation
# clientName

# Make a vector that populates the start date for Month filtering, segmenting, pivoting
########                       ########
############ REPLACE DATE  ############
date <- rep(start1,rows)
# Testing vector creation
# date

############ REPLACE QUERY  ############
primaryCue <- rep(could,rows)
# primaryCue

# Make a data frame from the created vectors
############ REPLACE QUERY  ############
could_queries_merged_1 <- data.frame(clientName,date,primaryCue,could_queries)
# Testing df creation
# pivotData
############ REPLACE QUERY  ############
# head(could_queries_merged_1,5)

############### QA CHECKPOINT ######################
# Write the data frame to an XLSX file
############ REPLACE QUERY  ############
# write_xlsx(could_queries_merged_1, "could_queries_1.xlsx")

# # # END could 1
# # #
# # #
# # #
# # #


# # # Start near 1
# # #
# # #
# # #
# # #

############ REPLACE QUERY  ############
near_queries <- search_analytics(
  siteURL = website, 
  startDate = start1,
  endDate = end1,
  dimensions = c("query", "page"),
  ##### REPLACE QUERY #####
  dimensionFilterExp = c("query~~near"),
  searchType="web",
  rowLimit = 1000000
)

# Dynamically get the number of rows from the GSC export so the created vectors match number of rows
############ REPLACE QUERY  ############
rows <- nrow(near_queries)
# Testing purposes - making sure rows vector near properly formed
# rows

# Make a vector that populates the client code
clientName <- rep(client,rows)
# Testing vector creation
# clientName

# Make a vector that populates the start date for Month filtering, segmenting, pivoting
########                       ########
############ REPLACE DATE  ############
date <- rep(start1,rows)
# Testing vector creation
# date

############ REPLACE QUERY  ############
primaryCue <- rep(near,rows)
# primaryCue

# Make a data frame from the created vectors
############ REPLACE QUERY  ############
near_queries_merged_1 <- data.frame(clientName,date,primaryCue,near_queries)
# Testing df creation
# pivotData
############ REPLACE QUERY  ############
# head(near_queries_merged_1,5)

############### QA CHECKPOINT ######################
# Write the data frame to an XLSX file
############ REPLACE QUERY  ############
# write_xlsx(near_queries_merged_1, "near_queries_1.xlsx")

# # # END near 1
# # #
# # #
# # #
# # #


# # # Start google 1
# # #
# # #
# # #
# # #

############ REPLACE QUERY  ############
google_queries <- search_analytics(
  siteURL = website, 
  startDate = start1,
  endDate = end1,
  dimensions = c("query", "page"),
  ##### REPLACE QUERY #####
  dimensionFilterExp = c("query~~google"),
  searchType="web",
  rowLimit = 1000000
)

# Dynamically get the number of rows from the GSC export so the created vectors match number of rows
############ REPLACE QUERY  ############
rows <- nrow(google_queries)
# Testing purposes - making sure rows vector google properly formed
# rows

# Make a vector that populates the client code
clientName <- rep(client,rows)
# Testing vector creation
# clientName

# Make a vector that populates the start date for Month filtering, segmenting, pivoting
########                       ########
############ REPLACE DATE  ############
date <- rep(start1,rows)
# Testing vector creation
# date

############ REPLACE QUERY  ############
primaryCue <- rep(google,rows)
# primaryCue

# Make a data frame from the created vectors
############ REPLACE QUERY  ############
google_queries_merged_1 <- data.frame(clientName,date,primaryCue,google_queries)
# Testing df creation
# pivotData
############ REPLACE QUERY  ############
# head(google_queries_merged_1,5)

############### QA CHECKPOINT ######################
# Write the data frame to an XLSX file
############ REPLACE QUERY  ############
# write_xlsx(google_queries_merged_1, "google_queries_1.xlsx")

# # # END google 1
# # #
# # #
# # #
# # #


# # # Start alexa 1
# # #
# # #
# # #
# # #

############ REPLACE QUERY  ############
alexa_queries <- search_analytics(
  siteURL = website, 
  startDate = start1,
  endDate = end1,
  dimensions = c("query", "page"),
  ##### REPLACE QUERY #####
  dimensionFilterExp = c("query~~alexa"),
  searchType="web",
  rowLimit = 1000000
)

# Dynamically get the number of rows from the GSC export so the created vectors match number of rows
############ REPLACE QUERY  ############
rows <- nrow(alexa_queries)
# Testing purposes - making sure rows vector alexa properly formed
# rows

# Make a vector that populates the client code
clientName <- rep(client,rows)
# Testing vector creation
# clientName

# Make a vector that populates the start date for Month filtering, segmenting, pivoting
########                       ########
############ REPLACE DATE  ############
date <- rep(start1,rows)
# Testing vector creation
# date

############ REPLACE QUERY  ############
primaryCue <- rep(alexa,rows)
# primaryCue

# Make a data frame from the created vectors
############ REPLACE QUERY  ############
alexa_queries_merged_1 <- data.frame(clientName,date,primaryCue,alexa_queries)
# Testing df creation
# pivotData
############ REPLACE QUERY  ############
# head(alexa_queries_merged_1,5)

############### QA CHECKPOINT ######################
# Write the data frame to an XLSX file
############ REPLACE QUERY  ############
# write_xlsx(alexa_queries_merged_1, "alexa_queries_1.xlsx")

# # # END alexa 1
# # #
# # #
# # #
# # #


# # # Start do 1
# # #
# # #
# # #
# # #

############ REPLACE QUERY  ############
do_queries <- search_analytics(
  siteURL = website, 
  startDate = start1,
  endDate = end1,
  dimensions = c("query", "page"),
  ##### REPLACE QUERY #####
  dimensionFilterExp = c("query~~do"),
  searchType="web",
  rowLimit = 1000000
)

# Dynamically get the number of rows from the GSC export so the created vectors match number of rows
############ REPLACE QUERY  ############
rows <- nrow(do_queries)
# Testing purposes - making sure rows vector do properly formed
# rows

# Make a vector that populates the client code
clientName <- rep(client,rows)
# Testing vector creation
# clientName

# Make a vector that populates the start date for Month filtering, segmenting, pivoting
########                       ########
############ REPLACE DATE  ############
date <- rep(start1,rows)
# Testing vector creation
# date

############ REPLACE QUERY  ############
primaryCue <- rep(do,rows)
# primaryCue

# Make a data frame from the created vectors
############ REPLACE QUERY  ############
do_queries_merged_1 <- data.frame(clientName,date,primaryCue,do_queries)
# Testing df creation
# pivotData
############ REPLACE QUERY  ############
# head(do_queries_merged_1,5)

############### QA CHECKPOINT ######################
# Write the data frame to an XLSX file
############ REPLACE QUERY  ############
# write_xlsx(do_queries_merged_1, "do_queries_1.xlsx")

# # # END do 1
# # #
# # #
# # #
# # #


# # # Start is 1
# # #
# # #
# # #
# # #

############ REPLACE QUERY  ############
is_queries <- search_analytics(
  siteURL = website, 
  startDate = start1,
  endDate = end1,
  dimensions = c("query", "page"),
  ##### REPLACE QUERY #####
  dimensionFilterExp = c("query~~is"),
  searchType="web",
  rowLimit = 1000000
)

# Dynamically get the number of rows from the GSC export so the created vectors match number of rows
############ REPLACE QUERY  ############
rows <- nrow(is_queries)
# Testing purposes - making sure rows vector is properly formed
# rows

# Make a vector that populates the client code
clientName <- rep(client,rows)
# Testing vector creation
# clientName

# Make a vector that populates the start date for Month filtering, segmenting, pivoting
########                       ########
############ REPLACE DATE  ############
date <- rep(start1,rows)
# Testing vector creation
# date

############ REPLACE QUERY  ############
primaryCue <- rep(is,rows)
# primaryCue

# Make a data frame from the created vectors
############ REPLACE QUERY  ############
is_queries_merged_1 <- data.frame(clientName,date,primaryCue,is_queries)
# Testing df creation
# pivotData
############ REPLACE QUERY  ############
# head(is_queries_merged_1,5)

############### QA CHECKPOINT ######################
# Write the data frame to an XLSX file
############ REPLACE QUERY  ############
# write_xlsx(is_queries_merged_1, "is_queries_1.xlsx")

# # # END is 1
# # #
# # #
# # #
# # #

# # # Start can 1
# # #
# # #
# # #
# # #

############ REPLACE QUERY  ############
can_queries <- search_analytics(
  siteURL = website, 
  startDate = start1,
  endDate = end1,
  dimensions = c("query", "page"),
  ##### REPLACE QUERY #####
  dimensionFilterExp = c("query~~can"),
  searchType="web",
  rowLimit = 1000000
)

# Dynamically get the number of rows from the GSC export so the created vectors match number of rows
############ REPLACE QUERY  ############
rows <- nrow(can_queries)
# Testing purposes - making sure rows vector can properly formed
# rows

# Make a vector that populates the client code
clientName <- rep(client,rows)
# Testing vector creation
# clientName

# Make a vector that populates the start date for Month filtering, segmenting, pivoting
########                       ########
############ REPLACE DATE  ############
date <- rep(start1,rows)
# Testing vector creation
# date

############ REPLACE QUERY  ############
primaryCue <- rep(can,rows)
# primaryCue

# Make a data frame from the created vectors
############ REPLACE QUERY  ############
can_queries_merged_1 <- data.frame(clientName,date,primaryCue,can_queries)
# Testing df creation
# pivotData
############ REPLACE QUERY  ############
# head(can_queries_merged_1,5)

############### QA CHECKPOINT ######################
# Write the data frame to an XLSX file
############ REPLACE QUERY  ############
# write_xlsx(can_queries_merged_1, "can_queries_1.xlsx")

# # # END can 1
# # #
# # #
# # #
# # #

month_1_queries <- rbind(who_queries_merged_1,what_queries_merged_1,when_queries_merged_1,where_queries_merged_1,why_queries_merged_1,how_queries_merged_1,does_queries_merged_1,have_queries_merged_1,has_queries_merged_1,are_queries_merged_1,which_queries_merged_1,will_queries_merged_1,was_queries_merged_1,should_queries_merged_1,would_queries_merged_1,could_queries_merged_1,near_queries_merged_1,google_queries_merged_1,alexa_queries_merged_1,
do_queries_merged_1,is_queries_merged_1,can_queries_merged_1)

write_xlsx(month_1_queries, "month_1_queries.xlsx")
# Write the data frame to an XLSX file
# write_xlsx(does_queries, "does_queries.xlsx")

You can also find the code in a Github gist.

Closing Thoughts on Voice Search Strategy & SEO

Stay tuned on this space! I’ll be publishing some more insight soon (ish) on how this work is valuable to your digital marketing agency’s strategy & planning, even if your voice search optimization doesn’t quite speak up for voice as soon as we think. This

%d bloggers like this: