Coder Social home page Coder Social logo

adobeanalyticsr's Introduction

adobeanalyticsr

Lifecycle: experimental

R Client for Adobe Analytics API 2.0

Connect to the Adobe Analytics API v2.0, which powers Analysis Workspace. The package was developed with the analyst in mind and will continue to be developed with the guiding principles of iterative, repeatable, timely analysis. New features are actively being developed, and we value your feedback and contribution to the process. Please submit bugs, questions, and enhancement requests as issues in this Github repository.

A special thanks to our company, Further (formally Search Discovery), for giving us the time, encouragement, and support to build out this package. There is no way this would have been possible without the opportunity to learn from and work with some of the most amazing people in the analytics industry.

A Note about 2.0 vs. 1.4

The Adobe Analytics v1.4 API, while on its way out, still has some functionality that is not (yet?) available in the v2.0 API. As such, the RSiteCatalyst package created by Randy Zwitch remains a useful package. While this is not a comprehensive list, some of the features that are available through RSiteCatalyst that are not available through the v2.0 API (and, by extension, are not available through this package) are:

  • Data Warehouse queries
  • Marketing Channel configuration and processing rules
  • Some configuration details for variables (eVar, prop, events)
  • Data Feed details

The v1.4 API also allows the user to pull data once they have web services access set up for their account and the client ID and client secret that comes along with that. In other words, it does not require that an Adobe Console API project be created, which is something that is required to use the v2.0 API. The benefit of getting an Adobe Console API project set up, though, is that the user then does not need web services access set up on an account-by-account basis to pull data using the package if using the OAUTH authentication. If using the JWT authentication method with v2.0 API, then a project does need to be created for each company account.

As a purely editorial side note, the creators and maintainers of this package would like to express their eternal gratitude to Randy for the work he put in to creating and maintaining RSiteCatalyst. His work brought the power of R combined with data pulled directly via the Adobe Analytics API to a global audience, and we can only hope (for ourselves and the analyst community writ large) that adobeanalyticsr can live up to the high standard he set with his work.

Install the package (recommended)

# Install from CRAN
install.packages('adobeanalyticsr')

# Load the package
library(adobeanalyticsr) 

Install the development version of the package

# Install devtools from CRAN
install.packages("devtools")

# Install adobeanayticsr from github
devtools::install_github('benrwoodard/adobeanalyticsr') 

# Load the package
library(adobeanalyticsr) 

Current setup process overview

There are four setup steps required to start accessing your Adobe Analytics data. The following steps are each outlined in greater detail in the following sections:

  1. Create an Adobe Console API Project
  2. Create and add the OAuth/JWT arguments to your .Renviron file.
  3. Set the type of authorization being used by calling aw_auth_with(type = ""). The type value should be jwt or oauth
  4. Get your authorization token using aw_auth(). Once the authorization type has been set (the previous step), this will look for .Renviron variables and complete the authorization.
  5. Get your company_id by using the function get_me().

1. Create an Adobe Console API Project

If you are using the OAuth authorization, regardless of how many different Adobe Analytics accounts you will be accessing, you only need a single Adobe Console API project (you will still need to have working user credentials for each account you want to access, but the Adobe Console API project is just the way you then get access to authenticate using those user credentials; yes...confusing!) If you are using the JWT authorization then you will need an Adobe Console API project created for each company you will be accessing. The following steps will get you setup on either of the different authorizations:

  1. Navigate to the following URL: https://console.adobe.io/integrations.
  2. Click the Create New Project button and select Empty Project
  3. Click the Add API button.
  4. Select the Experience Cloud product icon and then choose Adobe Analytics and click Next.
  5. The next series of steps depends on your choice of authorization.
  • OAuth
    1. Select the OAuth option and then click Next.
    2. Select Web as the platform where you want the integration.
    3. Add Default redirect URI https://adobeanalyticsr.com/token_result.html*.
    4. Add Redirect URI pattern https://adobeanalyticsr\.com/token_result\.html*.
  • JWT
    1. Select the Service Account (JWT) options and then click Next.
    2. Click on the Generate a Key Pair button. A config file will download onto your desktop.
    3. Select the product profiles to be included in the access and click Save configured API.

* This is simply a helper site we've set up in order to make it easier to generate a token. The site does not store any information.

Creating an Adobe Console API Project in under 60 seconds

2. Set up the .Renviron file

This file is essential to keeping your information secure. It also speeds up analysis by limiting the number of arguments you need to add to every function call.

  1. If you do not have an .Renviron file (if you have never heard of this file you almost certainly don't have one!), then create a new file and save it with the name .Renviron. You can do this from within the RStudio environment and save the file either in your Home directory (which is recommended; click on the Home button in the file navigator in RStudio and save it to that location) or within your project's working directory.

  2. Get the following variables from the OAuth project and add them to the file* (see Creating an Adobe Console API Project above):

    • (OAuth) AW_CLIENT_ID -- the client id found in the Adobe Developer Console
    • (OAuth) AW_CLIENT_SECRET -- the client secret key found in the Adobe Developer Console
    • (JWT) AW_PRIVATE_KEY -- unzip the downloaded config.zip file and move the .key file to a convenient location. An example file name is ~/aa_20_api/private.key. This variable, AW_PRIVATE_KEY, should reference the accurate path for the file.
    • (JWT) AW_AUTH_FILE -- The path of a JSON file containing fields with JWT authentication data. This file may be found packaged in the config.zip file, or you may create it yourself. See below.
  3. (Optional) Add AW_COMPANY_ID and AW_REPORTSUITE_ID variables once you know them (how to find available values for these two variables is described in step 4 below).

After adding these variables to the .Renviron file and saving it, restart your R session (Session > Restart R in RStudio) and reload adobeanalyticsr (library(adobeanalyticsr)).

* The format of variables in the .Renviron file is straightforward. If you add all four of the variables above, they would simply each be their own line in the file:

## If using OAuth 
AW_CLIENT_ID = "[OAuth client ID]"
AW_CLIENT_SECRET = "[OAuth client secret]"
AW_COMPANY_ID = "[Company ID]"
AW_REPORTSUITE_ID = "[RSID]"

## If using JWT 
AW_AUTH_FILE = "[auth_file.json]"
AW_PRIVATE_KEY = "[private.key]"
AW_COMPANY_ID = "[Company ID]"
AW_REPORTSUITE_ID = "[RSID]"

An example authentication JSON file contains the following at a minimum:

{
	"API_KEY":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
	"CLIENT_SECRET":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
	"ORG_ID":"xxxxxxxxxxxxxxxxxxxxxxxx@AdobeOrg",
	"TECHNICAL_ACCOUNT_ID":"[email protected]"
}

Other fields are simply ignored. Note: API_KEY means the same thing as CLIENT_ID.

3. Get your authorization token

The token is actually a lonnnnng alphanumeric string that is the what ultimately enables you to access your data:

OAuth process OAuth requires an interactive environment (see step 3 below), and the authentication token expires after 24 hours, which then requires repeating steps 2-9 below:

  1. In the console, enter aw_auth_with('oauth') and press Enter.
  2. Enter aw_auth() and press Enter.
  3. A browser window should appear that prompts you to log in to your Adobe Marketing Cloud account.
  4. Log in.
  5. You will then be redirected to adobeanalyticsr.com* and a screen that displays your token.*
  6. Copy the token (only).
  7. Return to the R console. You should see a prompt to Enter authorization code:
  8. Paste the token you copied and press Enter.
  9. You should see the confirmation message: "Successfully authenticated with OAuth"

As noted above, this token will expire every 24 hours, so you will have to periodically repeat this step.

* Again, this is simply a helper site I've set up in order to make it easier to generate a token. The site does not store any information.

JWT process JWT does not require an interactive environment and does not require a token refresh every 24 hours, but it does require a bit more work to set up initially (as described above). To authenticate using JWT:

  1. In the console, enter aw_auth_with('jwt') and press Enter.
  2. Enter aw_auth() and press Enter.
  3. You should see the confirmation message: "Successfully authenticated with JWT: access token valid until..."

4. Confirm the process worked and get available company_id and reports

The last step is to get your company_id (or, if you have access to multiple accounts, get the company_id you want to work with). This is also an excellent way to confirm that everything is set up correctly:

  1. In the console, type get_me() and press Enter.
  2. You should then see a list of all of the companies you have access to. The globalCompanyId value is what you will use to specify the company that you want to access. If you are working solely (or primarily) with one company, then consider adding the company_id as AW_COMPANY_ID in your .Renviron file as described in step 2 above. Otherwise, you can specify it within each function call that requires it.
  3. If you will be working solely (or primarily) with a single report suite, then consider adding the report suite ID (RSID) as AW_REPORTSUITE_ID in your file as described in step 2 above. You can retrieve all of the report suite IDs for a given company_id using the function aw_get_reportsuites(company_id = '[the company ID for account of interest]').

If you added any values to your .Renviron file (and then saved it!), then restart your R session (Session > Restart R in RStudio) and reload adobeanalyticsr (library(adobeanalyticsr)).

5. Pull some data!

You now should be set to start pulling data, typically starting with aw_get_metrics() and aw_get_dimensions() to get a list of available dimension and metric IDs, and then aw_freeform_table() to pull some data!

adobeanalyticsr's People

Contributors

benrwoodard avatar gilliganondata avatar charlie-gallagher avatar markedmondson1234 avatar jlsutherland avatar elalbaicin avatar

Stargazers

Jimmy Briggs avatar Alyssa Cuson avatar  avatar  avatar Wen avatar  avatar Robin Browne avatar Henry Leacock avatar Charlie Tysse avatar  avatar  avatar Patrick Little avatar Chisato avatar Peter avatar  avatar Jas Sohi avatar  avatar Alan Millington avatar

Watchers

 avatar Jason Morgan avatar  avatar Donal Phipps avatar  avatar Manuel Buitrago avatar  avatar  avatar  avatar

adobeanalyticsr's Issues

Search Clause Documentation

I really want to make a Christmas joke right now but I'll refrain. Below is documentation from the 2.0 api docs

Using clause Parameters
As noted above, the search parameter also includes the clause option. The clause parameter provides a powerful tool for filtering data. To use it, follow these rules:

It uses boolean operators AND, OR, and NOT.
It uses operators MATCH, CONTAINS, BEGINS-WITH, and ENDS-WITH.
It uses group conditions with parenthesis.
Strings are contained in single quotes.
Searches are case-insensitive.
If no operator is specified, a 'contains' match is performed.
Valid operators are 'match' and 'contains'.
Glob expressions are evaluated. If a literal * is needed, use \*.
Example Clause Statements
Only include results that match the string 'home page': MATCH 'home page'
Include pages that do not contain 'home page': NOT CONTAINS 'home page'
Include pages that do not contain 'home page' or 'about us', but do contain 'contact us': (NOT CONTAINS 'home page' OR NOT CONTAINS 'about us') AND (CONTAINS 'contact us')
Include pages that contain 'home page' or start with 'landing': CONTAINS 'home page' OR BEGINS-WITH 'landing'

https://github.com/AdobeDocs/analytics-2.0-apis/blob/master/reporting-guide.md#using-clause-parameters

`aw_get_calculatedmetrics()` - return comma-separated set of tags if `tags` is used in `expansion`

The tags argument for expansion in aw_get_calculatedmetrics() appears to return a list object in the tags column. Since many calculated metrics will have no tags or only a single tag, returning a commas-separated string with the tags seems like it would be cleaner to use, since this would, presumably, be returned primarily so that a subsequent call that uses tagnames would then be executed.

Convert arguments that accept a "comma-separated string" to accept a vector instead.

Currently, the following argument in aw_get_calculatedmetrics() will only include the tags column:

expansion = "tags, modified"

The following, however, will return both tags and modified:

expansion = "tags,modified"

This is because the space after the comma in the first example means that the second value does not get properly passed to the API.

I would actually prefer the following notation be the actual expected/accepted one:

expansion = c("tags", "modified")

But, at a minimum, using the existing notation but accounting for "comma-space" situations would potentially prevent frustration.

aw_get_calculatedmetrics() - `ownerId` causing errors

I can't get ownerId to work.

It's not clear from the documentation as to whether this should be using the owner.id or the owner.login value.

As an example, neither of these works:

Using the owner.id value

aw_get_calculatedmetrics(rsid = rsid,
                                company_id = company_id,
                                ownerId = "[added owner.id value from an unfiltered call]")

Using the owner.login value

aw_get_calculatedmetrics(rsid = rsid,
                                company_id = company_id,
                                ownerId = "added the owner.login value--email address--from a call w/ ownerFullName expansion]")

Both return:

Error in aw_call_api(req_path = urlstructure[1], company_id = company_id) : 
  Forbidden (HTTP 403).

The fact that I was trying to filter on values that I was getting from a less filtered version of the same function all means I do have access to that data.

daterangeweek auto top number

locate the position of the daterangeweek in the list of dimensions and check for if 0 and then change it with the number of weeks usinglength(seq(date_range, by = 'week'))

aw_get_metrics(...segmentable = FALSE) returns all metrics (segmentable and not)

I don't know if this is an API issue (in which case we can just document it) or whether it's an issue with the function.

  • segmentable = TRUE returns just the metrics that can be used in segments.
  • segmentable = FALSE, though, returns all metrics. In theory, it should just return the handful that are not available in segments (which I don't know why anyone would ever want that): bounces, unique visitors, etc.

I had to go digging and then experimenting to even confirm what "segmentable" was. Including this link as the one reference I found: https://experienceleague.adobe.com/docs/analytics/analyze/analysis-workspace/workspace-faq/aw-limitations.html?lang=en#known-limitations-in-analysis-workspace

Also for reference, through experimentation, these are the metrics that I expected segmentable = FALSE to return:

  • averagepagedepth
  • averagetimespentonpage
  • averagetimespentonsite
  • averagevisitdepth
  • bouncerate
  • bounces
  • entries
  • exits
  • firsttouchchannel.5
  • firsttouchchannel.6
  • firsttouchchannel.7
  • firsttouchchannel.8
  • itemtimespent
  • mobileviews
  • occurrences
  • orderspervisit
  • pagesnotfound
  • pageviewspervisit
  • singlevaluevisits
  • timespentvisit
  • timespentvisitor
  • visitors
  • visitorsdaily
  • visitorshourly
  • visitorsmonthly
  • visitorsquarterly
  • visitorsweekly
  • visitorsyearly

Include support for custom metrics

'metrics/' is not included when custom metrics are used in query

{"columnId": "5", "id": "metrics/event22" },
{"columnId": "6", "id": "cm300006896_5fac6262d1a4a8555835dc5c"}

0 results getting queried/returned when a daterange dimension is in a non-1st position

This was identified when I was simply exploring the difference in runtimes from ordering my dimensions in a "smart" way versus in an "obvious" (but slower, based on the API workings) way. Both examples were intended to return "complete" data.

This was for a 30-day period.

df_fast <- aw_freeform_report(company_id = company_id,
                              rsid = rsid,
                              date_range = c(start_date, end_date),
                              dimensions = c("mobiledevicetype", "lasttouchchannel", "daterangeday"),
                              metrics = c("visits", "pageviews", "orders", "revenue"),
                              top = c(10, 30, 0))

df_slow <- aw_freeform_report(company_id = company_id,
                              rsid = rsid,
                              date_range = c(start_date, end_date),
                              dimensions = c("daterangeday", "lasttouchchannel", "mobiledevicetype"),
                              metrics = c("visits", "pageviews", "orders", "revenue"),
                              top = c(0, 30, 10))

As expected, putting daterangeday last was much faster (4X).

But, df_fast also had more rows than df_slow. Further investigation turned up that df_fast had a number of rows with "0" values for all of the metrics.

The totals (sum) for each metric were identical across the two data frames.

Below are some of the "all zeros:"

image

I think what is going on is that, for daterange values, the API ensures that it returns a value for every date increment in the date range. Theoretically, this could occur for a very low-incidence metric even if a daterange dimension is at the top level. But, if a daterange value is farther down—which makes for more efficient querying—it's more likely to occur.

Is this just a lower-priority something to document? (Or maybe Adobe has already documented it?

Segment Comparison Venn Diagram QV

This would be fairly straightforward as it would be limited to an expected 2 dimensions and return results in a single line of data that could be turned into a venn diagram of some kind along with the data for review.

Sample request:
{
"rsid": "ageo1xxpnwsdi2020prod",
"globalFilters": [
{
"type": "dateRange",
"dateRange": "2020-10-26T00:00:00.000/2020-11-25T00:00:00.000"
}
],
"metricContainer": {
"metrics": [
{
"columnId": "metrics/visitors:::0",
"id": "metrics/visitors",
"filters": [
"0"
]
},
{
"columnId": "metrics/visitors:::1",
"id": "metrics/visitors",
"filters": [
"1"
]
},
{
"columnId": "metrics/visitors:::2",
"id": "metrics/visitors",
"filters": [
"2",
"3"
]
}
],
"metricFilters": [
{
"id": "0",
"type": "segment",
"segmentId": "Mobile_Hits"
},
{
"id": "1",
"type": "segment",
"segmentId": "First_Time_Visits"
},
{
"id": "2",
"type": "segment",
"segmentId": "Mobile_Hits"
},
{
"id": "3",
"type": "segment",
"segmentId": "First_Time_Visits"
}
]
},
"settings": {
"countRepeatInstances": true
},
"statistics": {
"functions": [
"col-max",
"col-min"
]
}
}

aw_freeform_table() - provide periodic query count updates

A current example of the messages when running aw_freeform_table():

Estimated runtime: 318.4sec./5.31min.
1 of 398 possible data requests complete. Starting the next 397 requests.
A total of 1985 rows have been pulled.

So, there's some information provided up front: an estimated runtime and then the fact that the first data request has run. But...then there's nothing.

It would be nice to get periodic updates on progress—not necessarily every request, but, based on the estimated total requests, every request or every 5 requests or every 10 requests. So, in the example above, logic could be that there are an estimated 397 requests, and that's greater than 200, so an "every 50" increment would be used:

Estimated runtime: 318.4sec./5.31min.
1 of 398 possible data requests complete. Starting the next 397 requests.
50 of 398 possible data requests complete. Starting the next 348 requests.
100 of 398 possible data requests complete. Starting the next 298 requests.
150 of 398 possible data requests complete. Starting the next 248 requests.
200 of 398 possible data requests complete. Starting the next 198 requests.
250 of 398 possible data requests complete. Starting the next 148 requests.
300 of 398 possible data requests complete. Starting the next 98 requests.
350 of 398 possible data requests complete. Starting the next 48 requests.
398 of 398 possible data requests complete. Starting the next 397 requests.
A total of 1985 rows have been pulled.

This would need some additional thought. It also could be, "provide ~15 updates" so the total estimated would be divided by 15 and then that's the increment that would then be used.

Alternative, a "messages" argument could have options to include these notifications or not.

Data mismatch between frontend and API return

Code: df <- aa_freeform_report(company_id = company_id, rsid = rsid_usp, date_range = Total_period, dimensions = c('prop2', 'daterangeday', 'prop1', 'lasttouchchannel'), metrics = 'visitors', segmentId = 's300008117_5dceed9bc945642acd98d070', top = top_values) [segment is 'group| --- side of brand' in the front end]

This is a hit level segment and so should be pulling only that particular side of brand data in which is what is happening when I create a freeform table in the front end with that segment applied. However the data pull has prop2=unspecified also included.

Sample output:
Prop2 daterangeday prop1 lasttouchchannel visitors
1 Unspecified Oct 5, 2020 Unspecified None 13
2 Unspecified Oct 6, 2020 Unspecified None 49
3 Unspecified Oct 7, 2020 Unspecified None 50
4 Unspecified Oct 8, 2020 Unspecified None 32
5 Unspecified Oct 9, 2020 Unspecified None 32
7 --- (right) Oct 5, 2020 not brand aligned None 11
8 --- (right) Oct 6, 2020 not brand aligned None 47

aw_getmetrics() -- change `expansion` to accept a vector

It seems a lot more natural to pass multiple values as a vector rather than as a comma-delimited string.

Current example:

expansion = "tags, categories"

Proposed update:

`expansion = c("tags", "categories")

Overall, this seems like a pretty dumb argument. I don't know what use case Adobe was imagining with this. But, I'm seeing this same thing on some other functions and will log separate issues there.

For now, I'm documenting against the current functionality, but, if we implement these enhancements, we'll need to update the documentation accordingly.

Authorization Process Issue

When a user attempts to re-authenticate the OAuth token, the user receives a 401 error. The current process is to attempt a minor API call function such as get_me() and after getting the 401 error, then trying the aa_token() function again. Need to sure up the authentication process.

image

"Simple" search support in aw_freeform_report

Add support for two "simple" use cases for the search argument in aw_freeform_report.

This is based on the premise that a common use case will be simply filtering for a single value.

Currently, to do the simplest of searches requires nesting a single quote within double quotes:

search = "'tablet'"

Add support for passing a simple string to search and then have that string be searched as a CONTAINS on the first dimension in the results:

So, search = "tablet" would actually execute search = "CONTAINS 'tablet'") (the CONTAINS isn't required in the API call, since that's the default).

Also, possibly (?) extend this support to a vector format if the user really wants a simple CONTAINS on multiple dimensions:

search = c("tablet", "search") would actually execute search = c("CONTAINS 'tablet'", "CONTAINS 'recliner'"))

`aw_get_calculatedmetrics()` - `tagnames` argument does not appear to be working.

I tried this on two separate companies. One only had one calculated metric with any tags, and it had two tags. The other had multiple metrics with a single tag.

The following is an example from the latter—GSK:

aw_get_calculatedmetrics(rsid = rsid,
                                company_id = company_id,
                                tagnames = "CXO")

In all cases, the tagnames filter had no impact on the output—the results were simply all calculated metrics.

`expansion` returning odd/incomplete results for `aw_get_calculatedmetrics()`

I made the following call:

aw_get_calculatedmetrics(rsid = rsid,
                                company_id = company_id)

I compared that to the results returned from this:

aw_get_calculatedmetrics(rsid = rsid,
                                company_id = company_id,
                                expansion = "reportSuiteName, ownerFullName, modified, tags, definition, compatability, categories")

There were only two additional columns added:

  • reportSuiteName -- that seems right/expected
  • siteTitle -- that...wasn't in the list of values

Any idea what might be going on here?

aw_anomaly_report() function 403 error

Error in aw_call_data_debug("reports/ranked", body = req_body, company_id = company_id) : 
  Forbidden (HTTP 403).

The api url:

 {"rsid":"xxxxxx","globalFilters":[{"type":"dateRange","dateRange":"2020-11-01T00:00:00.000/2020-12-01T23:59:59.999"}],"metricContainer":{"metrics":[{"columnId":"0","id":"metrics/visits","filters":["0"]}],"metricFilters":[{"id":"0","type":"dateRange","dateRange":"2020-11-01T00:00:00.000/2020-12-01T23:59:59.999"}]},"dimension":"variables/daterangeday","settings":{"countRepeatInstances":true,"limit":30,"page":0,"dimensionSort":"asc","nonesBehavior":"return-nones","includeAnomalyDetection":true}}

support segment dimension

example

{ "rsid": "xxxxx", "globalFilters": [ { "type": "segment", "segmentId": "s300006681_5fb4322d9bfec132bd9dbd73" }, { "type": "dateRange", "dateRange": "2020-10-01T00:00:00.000/2020-11-17T00:00:00.000" } ], "metricContainer": { "metrics": [ { "columnId": "metrics/orders:::0", "id": "metrics/orders", "filters": [ "STATIC_ROW_COMPONENT_1" ] }, { "columnId": "metrics/orders:::2", "id": "metrics/orders", "filters": [ "STATIC_ROW_COMPONENT_3" ] }, { "columnId": "metrics/orders:::4", "id": "metrics/orders", "filters": [ "STATIC_ROW_COMPONENT_5" ] }, { "columnId": "metrics/orders:::6", "id": "metrics/orders", "filters": [ "STATIC_ROW_COMPONENT_7" ] } ], "metricFilters": [ { "id": "STATIC_ROW_COMPONENT_1", "type": "segment", "segmentId": "s300006681_5fb436e8c89a963fe7b144fc" }, { "id": "STATIC_ROW_COMPONENT_3", "type": "segment", "segmentId": "s300006681_5fb436e88b03436b0b75d7d1" }, { "id": "STATIC_ROW_COMPONENT_5", "type": "segment", "segmentId": "s300006681_5fb436e87d03f65a10e92c56" }, { "id": "STATIC_ROW_COMPONENT_7", "type": "segment", "segmentId": "s300006681_5fb436e81212e663fcb463b3" } ] }, "settings": { "countRepeatInstances": true, "dimensionSort": "asc" }, "statistics": { "functions": [ "col-max", "col-min" ] } }

change function names to aw_verbelement

it's a minor thing but as you have been adding recommendations I've seen you utilize a naming convention that makes good sense. Using 'aw_' to prevent conflicts with other functions but then concatenate the action/verb and name of the element. example:
aw_get_calculatedmetrics to aw_getcalculatedmetrics
aw_get_metrics to aw_getmetrics
aw_get_dimensions to aw_getdimensions
...

Simplify where simplification will not remove recognition:
aw_freeform_report to aw_freeform
aw_anomaly_report to aw_anomaly

*where the expected result is a table of data, report is not needed.

What do you think?

aw_freeform_table() - more detail if a request fails partway through

I got the following messages when running an aw_freeform_table() query:

Estimated runtime: 318.4sec./5.31min.
1 of 398 possible data requests complete. Starting the next 397 requests.
Request failed [429]. Retrying in 7 seconds...
A total of 1985 rows have been pulled.

There is no information about the failed request:

  • What a "429" failure means
  • Where in the process the failure happened (see #70 — that enhancement would help with this a bit)
  • Whether the retry was explicitly successful (vs. that query just got skipped?)

At a minimum, something like the following would be reassuring:

Estimated runtime: 318.4sec./5.31min.
1 of 398 possible data requests complete. Starting the next 397 requests.
Request failed [429]. Retrying in 7 seconds...
Retry successful. Continuing with additional requests...
A total of 1985 rows have been pulled.

aw_get_calculatedmetric_byid() - cannot get this to work at all

May not be a bug, but I just can't get this to work.

The code:

aw_get_calculatedmetric_byid(company_id = company_id,
                                                  id = "cm300008117_5eb9b63009282640d73ca30b")

The id I pulled straight from an aw_get_calculatedmetrics() call. I tried several different values, both calculated metrics I owned and ones that I didn't, and I got a NULL result in all cases.

get_users question

@benrwoodard Is it possible to get how many times the user logged in for the last 2 months' time frame? Does Adobe Analytics API 2.0 have that available?

aa_freeform_table() is limited to 6 dimensions

There is nothing inherent in the v2 API preventing aa_freeform_table() to infinitely recurse through dimensions. It would be really nice to have that ability. Even if there is a practical / time limit, simply having the function code such that it is fully dynamic would be preferred.

Support metric level segmentation

When comparing metrics across segments it would be good to be able to segment on the metric itself so you can pull different results for each metric.

image

pretty name for dimensions and metrics

Using the id and title/name, create a list of pretty names for each dimension and metric in the call and then return back the names by names(dat) <- prettynames
Theoretically, this would add a few seconds to the function time but would be an additional attribute int he function so it could be turned on and off.
Call metrics
Call dimensions
Trim to id/name
join with expected final names and produce final pretty name list to use on final output if TRUE

finalmnames error message without metric filters aw_workspace_report() function

When attempting to use the aw_workspace_report() function on a JSON file without 'metric filters' one receives the following error 'object 'finalmnames' not found'.

From a prioritization perspective this is likely low value as one could use aw_freeform_table() to successfully fetch the 'same' request.

Image of error message below. The text that is within the sample json file is within the text file below (can't upload json file here).

image

sampleRequest.txt

Time handling in the freeform_report() function

scenarios

  1. user includes 'daterangeday' in the dimension list of 3 dimensions and then adds 'top=(2, 5)' to the list for the limits expecting the data granularity to calculated.
  2. User includes "timegranularity" attribute and expects all dimensions to be broken down by that type of granularity.
  3. User adds 'daterange...." anywhere in the dimension list and expects the breakdown to result in all the corresponding rows as a result

aw_anomaly_report granularity = week giving an error with quickView = T

When using granularity=week along with quickView = T, it shows an error message:
Error in FUN(X[[i]], ...) : object 'day' not found
(works fine when quickView argument removed)

Sample code used:
test <- aw_anomaly_report(date_range = c('2020-10-1', '2020-11-10'),
metrics = c('visits','visitors'),
granularity = 'week',
quickView = T)

List of users

@benrwoodard Are there any plans for enhancements for providing a list of users when they access Adobe Analytics? Or is it not available via Adobe 2.0 API?

workspace_report function enhancement

The current function is limited to basic pulls. The next iteration will require the end user to create a json file and pass that path into the arguments but it will accept any copied json request from the debugger.

Add support for dynamically defining segments

Having the ability to fully defined a segment within R—rather than needing to define it in AW and then reference it by ID—would be useful.

The use case would be to be able to have a base segment and then swap out multiple "one change" values for it.

For instance, wanting to look at mobile traffic for each channel (in a way that simply using multiple dimensions wouldn't work) and being able to pull a list of channels and then have a function that combines each channel with "Mobile Phone" in a segment.

This would make for code that could be readily repurposed across different companies.

aw_get_calculatedmetrics() - `favorite` shows `0` instead of `FALSE` for the default value

favorite is a Boolean. And, in general, 0 = FALSE and 1 = TRUE, but the parameter list shows that this is set to 0.

I actually tried setting it to 1 in a call, and the function returned all calculated metrics. I had to set it to TRUE to get that to work.

I think this is as simple as changing function definition to be favorite = FALSE, but I don't know if there are any downstream ramifications of that.

aw_freeform_table() - provide actual runtime when query is complete

Current example of messages when running aw_freeform_table():

Estimated runtime: 318.4sec./5.31min.
1 of 398 possible data requests complete. Starting the next 397 requests.
A total of 1985 rows have been pulled.

Since queries will often get run multiple times with no or minimal adjustments, it would be nice to have one more line that reports how long the actual runtime was:

Estimated runtime: 318.4sec./5.31min.
1 of 398 possible data requests complete. Starting the next 397 requests.
A total of 1985 rows have been pulled.
Actual runtime: 284.3/ 4.73min.

Paid License Required?

Can you confirm a paid license is required in order to connect to the Adobe Analytics API when setting up the Adobe Console API Project here https://console.adobe.io/integrations?

If so, how do I purchase this subscription, is the subscription tied to my account or maybe the organization I'm working with?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.