Coder Social home page Coder Social logo

ganalytics's People

Contributors

chipoglesby avatar jdeboer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ganalytics's Issues

Methods to coerce `ganalytics` objects into `googleAnalyticsR` object

Aim: To be able to use the ganalytics expression language with googleAnalyticsR. This is to take advantage of the Google Analytics Reporting API Version 4 interface made available from googleAnalyticsR while also continuing support for ganalytics expressions.

The following coercion functions have been tested and appear to result in mostly similar object structures with googleAnalyticsR. I am yet to test whether those objects are then accepted by the googleAnalyticsR::google_analytics_4 function and whether that function still produces the expected outputs. If so, then the next step is to finish the definitions for these coercion functions to cover any remaining object classes.

metric_operators <- c(
  "EQUAL" = "==",
  "LESS_THAN" = "<",
  "GREATER_THAN" = ">",
  "BETWEEN" = "<>"
)

dimension_operators <- c(
  "REGEXP" = "=~",
  "PARTIAL" = "=@",
  "EXACT" = "==",
  "IN_LIST" = "[]",
  "NUMERIC_LESS_THAN" = "<",
  "NUMERIC_GREATER_THAN" = ">",
  "NUMERIC_BETWEEN" = "<>"
)

negated_operators <- c(
  "!=", "!~", "!@", ">=", "<="
)

setClass("dim_fil_ga4")
setClass("met_fil_ga4")
setClass("segmentFilterClause_ga4")
setClass("orFiltersForSegment_ga4")
setClass("segmentSequenceStep_ga4")
setClass("simpleSegment_ga4")
setClass("sequenceSegment_ga4")
setClass("segmentFilter_ga4")
setClass("segmentDef_ga4")

get_expression_details <- function(from, var_operators) {
  varName <- as.character(Var(from))
  names(varName) <- sub("^ga:", "", varName)
  operator <- Comparator(from)
  negated <- operator %in% negated_operators
  if(negated) operator <- Not(operator)
  operator_lookup_index <- match(as.character(operator), var_operators)
  operator_name <- names(var_operators)[operator_lookup_index]
  operand <- as.character(Operand(from))
  expressions <- character(0)
  minComparisonValue <- character(0)
  maxComparisonValue <- character(0)
  if(operator == "<>") {
    minComparisonValue <- operand[1]
    maxComparisonValue <- operand[2]
  } else if(inherits(from, ".metExpr")) {
    minComparisonValue <- operand
  } else {
    expressions <- operand
  }
  list(
    varName = varName,
    operator = operator,
    operator_name = operator_name,
    negated = negated,
    expressions = expressions,
    minComparisonValue = minComparisonValue,
    maxComparisonValue = maxComparisonValue
  )
}

setAs("gaDimExpr", "dim_fil_ga4", def = function(from, to) {
  dim_operation <- get_expression_details(from, dimension_operators)
  x <- list(
    dimensionName = dim_operation$varName,
    not = dim_operation$negated,
    operator = dim_operation$operator_name,
    expressions = as.list(as.character(Operand(from))),
    caseSensitive = FALSE
  )
  class(x) <- "dim_fil_ga4"
  x
})

setAs("gaMetExpr", "met_fil_ga4", def = function(from, to) {
  met_operation <- get_expression_details(from, metric_operators)
  x <- list(
    metricName = met_operation$varName,
    not = met_operation$negated,
    operator = met_operation$operator_name,
    comparisonValue = as.character(Operand(from))
  )
  class(x) <- "met_fil_ga4"
  x
})

setAs("gaDimExpr", "segmentFilterClause_ga4", def = function(from, to) {
  exp_details <- get_expression_details(from, dimension_operators)
  segmentDimensionFilter <- list(
    dimensionName = exp_details$varName,
    operator = exp_details$operator_name,
    caseSensitive = NULL,
    expressions = exp_details$expressions,
    minComparisonValue = exp_details$minComparisonValue,
    maxComparisonValue = exp_details$maxComparisonValue
  )
  class(segmentDimensionFilter) <- "segmentDimFilter_ga4"
  x <- list(
    not = exp_details$negated,
    dimensionFilter = segmentDimensionFilter,
    metricFilter = NULL
  )
  class(x) <- "segmentFilterClause_ga4"
  x
})

setAs("gaMetExpr", "segmentFilterClause_ga4", def = function(from, to) {
  from <- as(from, "gaSegMetExpr")
  as(from, to)
})

setAs("gaSegMetExpr", "segmentFilterClause_ga4", def = function(from, to) {
  exp_details <- get_expression_details(from, metric_operators)
  scope <- c("perHit" = "HIT", "perSession" = "SESSION", "perUser" = "USER")[[ScopeLevel(from)]]
  segmentMetricFilter <- list(
    scope = scope,
    metricName = exp_details$varName,
    operator = exp_details$operator_name,
    comparisonValue = exp_details$minComparisonValue,
    maxComparisonValue = exp_details$maxComparisonValue
  )
  class(segmentMetricFilter) <- "segmentMetFilter_ga4"
  x <- list(
    not = exp_details$negated,
    dimensionFilter = NULL,
    metricFilter = segmentMetricFilter
  )
  class(x) <- "segmentFilterClause_ga4"
  x
})

setAs("orExpr", "orFiltersForSegment_ga4", def = function(from, to) {
  x <- list(
    segmentFilterClauses = lapply(from, as, "segmentFilterClause_ga4")
  )
  class(x) <- "orFiltersForSegment_ga4"
  x
})

setAs("andExpr", "simpleSegment_ga4", def = function(from, to) {
  x <- list(
    orFiltersForSegment = lapply(from, as, "orFiltersForSegment_ga4")
  )
  class(x) <- "simpleSegment_ga4"
  x
})

setAs("gaSegmentSequenceStep", "segmentSequenceStep_ga4", def = function(from, to) {
  matchType <- if(from@immediatelyPrecedes) "IMMEDIATELY_PRECEDES" else "PRECEDES"
  x <- c(
    as(as(from@.Data, "andExpr"), "simpleSegment_ga4"),
    list(matchType = matchType)
  )
  class(x) <- "segmentSequenceStep_ga4"
  x
})

setAs("gaSegmentSequenceFilter", "sequenceSegment_ga4", def = function(from, to) {
  segmentSequenceSteps <- lapply(from, as, "segmentSequenceStep_ga4")
  x <- list(
    segmentSequenceSteps = segmentSequenceSteps,
    firstStepShouldMatchFirstHit = from[[1]]@immediatelyPrecedes
  )
  class(x) <- "sequenceSegment_ga4"
  x
})

setAs("gaSegmentConditionFilter", "segmentFilter_ga4", def = function(from, to) {
  x <- list(
    not = IsNegated(from),
    simpleSegment = as(from, "simpleSegment_ga4"),
    sequenceSegment = NULL
  )
  class(x) <- "segmentFilter_ga4"
  x
})

setAs("gaSegmentSequenceFilter", "segmentFilter_ga4", def = function(from, to) {
  x <- list(
    not = IsNegated(from),
    simpleSegment = NULL,
    sequenceSegment = as(from, "sequenceSegment_ga4")
  )
  class(x) <- "segmentFilter_ga4"
  x
})

setAs("gaSegmentFilterList", "segmentDef_ga4", def = function(from, to) {
  x <- list(
    segmentFilters = lapply(from, as, "segmentFilter_ga4")
  )
  class(x) <- "segmentDef_ga4"
  x
})

Document S4 methods

All user-level objects in a package (including S4 classes and methods) should have documentation entries

Error: could not find function "new_oauth"

Hi.

In first thank you for this an interesting realisation GA APi access from R.

But seems now I can't get it worked. I follow instructions from README.

install_github(repo = "ganalytics", username = "jdeboer")
install.packages(c("plyr", "stringr", "RJSONIO", "Rook", "httpuv"))

then restart R-session.

library(ganalytics)
Sys.setenv(GANALYTICS_CONSUMER_ID = "myKey",
GANALYTICS_CONSUMER_SECRET = "mySecret")
ga.query <- GaQuery(profileID)
GetGaData(ga.query)
Error in GetGaData(ga.query) : could not find function "new_oauth"

I also trid pass key and secret to GetGaData with same results.

Does I forgot about something?

Check to perform: Packages should generally not write in the users' filespace

As per package development guidelines:
"Packages should not write in the users' home filespace, nor anywhere else on the file system apart from the R session's temporary directory (or during installation in the location pointed to by TMPDIR: and such usage should be cleaned up). Installing into the system's R installation (e.g., scripts to its bin directory) is not allowed.
Limited exceptions may be allowed in interactive sessions if the package obtains confirmation from the user.

Help for Expr()?

When I type ?Expr() I get a no documentation for function 'Expr' error. That is a function in the package, right? Should it have documentation available?

Source fails to install

Fails to install:

--->  Configuring R-ganalytics
Executing:  cd "/opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_R_R-ganalytics/R-ganalytics/work/ganalytics-0.10.7" && /opt/local/bin/R CMD build . --no-manual --no-build-vignettes --keep-empty-dirs 
* checking for file ‘./DESCRIPTION’ ... OK
* preparing ‘ganalytics’:
* checking DESCRIPTION meta-information ... OK
* checking for LF line-endings in source and make files and shell scripts
* checking for empty or unneeded directories
Omitted ‘LazyData’ from DESCRIPTION
* building ‘ganalytics_0.10.7.tar.gz’

--->  Building R-ganalytics
xinstall: mkdir /opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_R_R-ganalytics/R-ganalytics/work/build
Executing:  cd "/opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_R_R-ganalytics/R-ganalytics/work/ganalytics-0.10.7" && /opt/local/bin/R CMD INSTALL . --library=/opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_R_R-ganalytics/R-ganalytics/work/build --install-tests 
* installing *source* package ‘ganalytics’ ...
** using staged installation
** R
** demo
** inst
** tests
** byte-compile and prepare package for lazy loading
in method for ‘coerce’ with signature ‘"gaSegmentSequenceFilter","json"’: no definition for class “json”
in method for ‘coerce’ with signature ‘"gaDynSegment","json"’: no definition for class “json”
in method for ‘coerce’ with signature ‘"gaDynSegment","json"’: no definition for class “json”
Error : in method for ‘SortBy’ with signature ‘object=".query"’:  arguments (‘desc’, ‘type’) after ‘...’ in the generic must appear in the method, in the same place at the end of the argument list
Error: unable to load R code in package ‘ganalytics’
Execution halted
ERROR: lazy loading failed for package ‘ganalytics’
* removing ‘/opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_R_R-ganalytics/R-ganalytics/work/build/ganalytics’
Command failed:  cd "/opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_R_R-ganalytics/R-ganalytics/work/ganalytics-0.10.7" && /opt/local/bin/R CMD INSTALL . --library=/opt/local/var/macports/build/_opt_PPCSnowLeopardPorts_R_R-ganalytics/R-ganalytics/work/build --install-tests 
Exit code: 1
Error: Failed to build R-ganalytics: command execution failed

Install fails outh_listener

I am having a difficult time getting this package to install using devtools.

I keep getting the same error using the latest versions of R and Rstudio

oauth_listener() needs an interactive environment

Any help is appreciated as I was able to install other packages with devtools:install_github()

Update deprecated function documentation

as per guidelines described by .Deprecated()
"The original help page for these functions is often available at help("oldName-deprecated") (note the quotes). Functions should be listed in help("pkg-deprecated") for an appropriate pkg, including base."

Implement automatic no (or minimised) sampling technique

Implement an optional re-sampling technique to take the reported sample rate and if not NaN or not NA or not 100% but a number greater than 0 and less than 1, then use this to split the date range further if not already at daily level.

Allow querying more than 10 metrics at a time

query <- GaQuery()

Metrics(query) <- c("users", "sessions", "pageviews", "bounceRate", "timeOnSite", "goalCompletionsAll", "transactions", "transactionRevenue", "totalEvents", "uniquePageviews", "goal1Completions", ...)

metrics <- Metrics(query)
dimensions <- Dimensions(query)

kMaxApiQueryMetrics <- 10

metricGroups <- split(metrics, ceiling(seq_along(metrics) / kMaxApiQueryMetrics))

responseDataFramesList <- lapply(metricGroups, function(queryMetrics) {
  Metrics(query) <- queryMetrics
  GetGaData(query)
})

response <- Reduce(function(x, y) {join(x, y, by = dimensions)}, responseDataFramesList)

ganalytics DSL suggestions

Taking an example from http://www.slideshare.net/johanndeboer/web-analytics-with-r-melb-urn:

GaAnd( 
  GaExpr('keyword', '@', 'buy'), 
  GaOr( 
    GaExpr('city', '~', '^(Sydney|Melbourne)$'), 
    GaExpr('isTablet', '=', ‘Yes’) ) )

it would be relatively straightforward to allow you to write

GaExpr('keyword', '@', 'buy') && 
  (GaExpr('city', '~', '^(Sydney|Melbourne)$') || 
   GaExpr('isTablet', '=', ‘Yes’))

just by adding the appropriate methods for && and ||.

But I think it would be relatively straightforward to go even further and be able to write

GaAutoExpr(keyword %matches% "buy" && 
  (city %in% c("Sydney", "Melbourne") || isTablet == TRUE))

using the principles described in http://adv-r.had.co.nz/dsl.html.

Language for defining segments

Example of a proposed idea for expressing a sequence:

segment(
  perUser(
    expr1, # treat an expression as 'condition type segment filter' by default
    perHit(
      metrixExpr1
    )
  ),
  sequence(
    epxr2,
    then(expr3), # 'then' means 'immediately followed by'
    later(expr4) # 'later' means 'followed by', but not necessarily immediately.
  ),
  sequence(
    first(expr5), # First expressly means 'first interaction' within the date range.
    then(expr6), # By default, treat an expression within a sequence as happening
    expr7 # at any point after any preceding steps in the sequence, i.e. 'later'.
  )
)

handle server to server auth

Using google JWT.
i.e. in node js googleapis it works like that:

var google = require('googleapis');
var analytics = google.analytics({
    version: 'v3'
});
var jwtClient = new google.auth.JWT(
    config.ga.client_email,
    null,
    config.ga.private_key, ['https://www.googleapis.com/auth/analytics.readonly'],
    null)

Then you can access your data as follow:

analytics.get({
        'ids': 'ga:123456789',
        'start-date': timestamp_start,
        'end-date': timestamp_start,
        'metrics': 'ga:sessions',
        'dimensions': 'ga:socialActivityContentUrl',
        'sort': '-ga:sessions',
        'max-results': 10000,
        auth: jwtClient
    })

Therefore, you only need an email and private key and it does the rest for you (no need to auth via a webpage).

[README] Set your system environment variables

For set your system environment variables you can use Sys.setenv(GANALYTICS_CONSUMER_ID = "<Your client ID>", GANALYTICS_CONSUMER_SECRET = "<Your client secret>"). Also you can use .Renviron on unix-like systems.

Update Dimensions & Metrics to recent changes in datapoints

For example a Query cannot use the experimentId, experimentVariant dimensions

GaDimensions(gaQuery) <- c("date","experimentId")
Error in validObject(.Object) :
invalid class “gaDimVar” object: Invalid GA dimension name: experimentId

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.