Introduction to ActivityInfo and R

Introduction

This tutorial is about the ActivityInfo R Package that is a client used to access to the ActivityInfo REST API. While this is an API client, names of functions and arguments are modeled more closely to web user interface to facilitate its use.

With this client, you can programmatically obtain and modify your data. You can also manage users, create new databases and forms, or define reports. Any thing else that is possible through ActivityInfo's user interface can be automated using the API and this R package.

Install the R client

First, you should install ActivityInfo API R client in your system.

# install.packages("devtools")
devtools::install_github("bedatadriven/activityinfo-R")

Then, put the library call at the top of your script file.

library(activityinfo)
library(dplyr)

If you are using the ActivityInfo Self-Managed Server, you must provide the URL of your server using activityInfoRootUrl

Authentication

In order to access to the ActivityInfo API, you must authenticate to the server with a personal API token. You can generate a personal access token from the Profile Settings page in ActivityInfo. Logging in by email and password through the API is now deprecated and insecure.

activityInfoToken("2d6016c9cb3be78954eb396f806a20e9")

After the authentication process has been successfully completed, a prompt will ask if the token file named .activityinfo.server.credentials should be written to your home directory. Only write the file to your home directory if this is secure. Don't share or publish this token file and preserve securely as it contains your personal access token.

If you would like to avoid prompts, set prompt = FALSE to explicitly do this, including for Shiny server apps or non-interactive scripts.

activityInfoToken("2d6016c9cb3be78954eb396f806a20e9", prompt = FALSE)

Databases

You can list the databases that you own or have been shared with you using [activityinfo::getDatabases]. Use the asDf argument to get the list as a data.frame:

dbList <- getDatabases()
head(dbList)

In order to get details about a specific database, you can use [activityinfo::getDatabaseTree], or [activityinfo::getDatabaseResources] to return a data.frame with the list of resources in the database. "Resources" include forms, subforms, folders, and reports.

resources <- getDatabaseResources("cfcdyr0kq6ik2wmf")
#> Warning in activityInfoAuthentication(): Connecting to activityinfo.org anonymously...
head(resources)
#> # A tibble: 6 × 5
#>   id                label           type     parentId         visibility
#>   <chr>             <chr>           <chr>    <chr>            <chr>     
#> 1 reference         Reference Data  FOLDER   cfcdyr0kq6ik2wmf REFERENCE 
#> 2 csqojmfkq6jsm9n3x Sub-sector      FORM     reference        REFERENCE 
#> 3 c7b2moekq6ikasi2  Partner         FORM     reference        REFERENCE 
#> 4 csmqj7ltsfmybk10f Locations       SUB_FORM ceam1x8kq6ikcujg PRIVATE   
#> 5 c9ik9ralujvfdhfo  Monthly reports SUB_FORM ceam1x8kq6ikcujg PRIVATE   
#> 6 cc605xmlbgj5pee9  Monthly reports SUB_FORM ceam1x8kq6ikcujg PRIVATE

Forms

In order to get the form or sub-form schemas that you have access to, use getFormSchema(formId) call, which retrieves the the form's schema, including a list of fields in the form:

schema <- getFormSchema("ceam1x8kq6ikcujg")
#> Warning in activityInfoAuthentication(): Connecting to activityinfo.org anonymously...
head(schema, 4)
#> $id
#> [1] "ceam1x8kq6ikcujg"
#> 
#> $schemaVersion
#> [1] 43
#> 
#> $databaseId
#> [1] "cfcdyr0kq6ik2wmf"
#> 
#> $label
#> [1] "Projects"

You can find a form's ID from your browser's address bar when you have the form page open:

The form id is the part following "form/"
The form id is the part following "form/"

Getting records

You can get the records from an ActivityInfo form as a dplyr-compatible table. Let's retrieve the list of projects from the Simple 3W template

records <- getRecords("ceam1x8kq6ikcujg") |> collect()
#> Warning in activityInfoAuthentication(): Connecting to activityinfo.org anonymously...

#> Warning in activityInfoAuthentication(): Connecting to activityinfo.org anonymously...

#> Warning in activityInfoAuthentication(): Connecting to activityinfo.org anonymously...
head(records)
#> # ActivityInfo tibble: Remote form: Projects (ceam1x8kq6ikcujg)
#> # A tibble:            6 × 23
#>   `_id`       `_lastEditTime` Organization `Organization Name` `Sub-Sector` `Sub-sector Sector` `Sub-sector Name` Location `Admin 2 State/Region`
#>   <chr>                 <dbl> <chr>        <chr>               <chr>        <chr>               <chr>             <chr>    <chr>                 
#> 1 cphnje3kq6…      1624284965 c9pinkskq6n… The Fred Hollows F… cu6zg2hkq6j… c8bob2wkq6jrbgz3k   Basic Health Care c9h8zra… cqefrvkkq6jnidgq      
#> 2 cilhx8pkq6…      1624284965 cwhjya2kq6n… United Nations Chi… czhoavkkq6j… c8iitckq6jr1ms3h    Quality Basic Ed… ccri8n6… c6qc7rfkq6jnidfb      
#> 3 cb1xxe2kq6…      1624284965 cndrfpgkq6n… American Refugee C… c92dsnnkq6j… c8bob2wkq6jrbgz3k   Malaria Programme cl8mt7l… c4w2g9bkq6jnidfk      
#> 4 cfpwparkq6…      1624284965 cqw5pxtkq6n… Pact Global Microf… cgrx56xkq6j… c4hp3bmkq6jrfno3l   Microfinance      criyaet… cvira0gkq6jnidfl      
#> 5 cwt9ttukq6…      1654689264 cqw5pxtkq6n… Pact Global Microf… cgrx56xkq6j… c4hp3bmkq6jrfno3l   Microfinance      cckhmvl… ctw2augkq6jnidfj      
#> 6 cqs04chkq6…      1624284965 cctqkddkq6n… Karuna Mission Soc… czhoavkkq6j… c8iitckq6jr1ms3h    Quality Basic Ed… cl5oqz5… cm1j7eskq6jnidff      
#> # ℹ 14 more variables: `Admin 2 Name` <chr>, Locations <dbl>, `COVID-Related` <chr>, Sector <lgl>, `Funding received` <lgl>,
#> #   `Project title` <chr>, `Project start month` <chr>, `Project end month` <chr>, `Project status` <chr>, `Suspension reason` <lgl>,
#> #   Remarks <chr>, `Monthly reports...21` <dbl>, Validated <lgl>, `Monthly reports...23` <dbl>

Note that we pipe the records to [dplyr::collect], which actually retrieves all the records from the server.

For forms with tens of thousands of records, you may want to apply filtering to narrow down the results before downloading all the records from the server. You can use the [dplyr::filter] function to apply a filter:

unicef <- getRecords("ceam1x8kq6ikcujg", prettyColumnStyle())  |> 
  filter(`Organization Name` == "United Nations Childrens Fund") |>
  collect()
#> Warning in activityInfoAuthentication(): Connecting to activityinfo.org anonymously...

#> Warning in activityInfoAuthentication(): Connecting to activityinfo.org anonymously...

#> Warning in activityInfoAuthentication(): Connecting to activityinfo.org anonymously...

This will send the filter to the server, and only download matching records.

Updating records

You can also use the R package to add, update, and import records. For single records you can use the [activityinfo::addRecord] and [activityinfo::updateRecord] functions:

addRecord(formId = "cxy123", fieldValues = list(
    text_field = "Alice Jones",
    multi_line_text = "Line 1\nLine 2",
    date_of_birth = "1980-01-01",
    week_project_start = "2022W1",
    month = "2023-06",
    quantity_field = 42.0, 
    location = list(latitude = 52.0705, longitude = 4.3)))

updateRecord(formId = "cxy123", recordId = "" fieldValues = list(
    text_field = "Alice Smith"))

For adding or updating many records at once, you can use the [activityinfo::importRecords] function.

Adding and modifying forms

You can also add new forms and modify existing form schemas. You can add or remove fields from a form, or add an entirely new form.

The example below will add a new database, and then add a new form for a survey to the database.

surveyDb <- addDatabase("Surveys")
surveySchema <- formSchema(
  databaseId = surveyDb$databaseId,
  label = "My new survey",
  elements = list(
    textFieldSchema(
      label = "What is your name?",
      code = "NAME",
      description = "Please provide your full name",
      required = TRUE
    ),
    singleSelectFieldSchema(
      label = "What is your sex?",
      code = "SEX",
      options = c("Female", "Male", "Prefer not to answer"),
      required = TRUE
    ),
    singleSelectFieldSchema(
      label = "Are you pregnant",
      relevanceRule = "SEX != 'Male'",
      options = c("Yes", "No"),
      required = TRUE
    )
  )
)
surveyForm <- addForm(survey)

Managing users

The R package can also be used to automate user management for a database.

For example, you could read a list of users from Active Directory or other external source and automatically add them to an ActivityInfo database using [activityinfo::addDatabaseUser]:


addDatabaseUser(
  databaseId = databaseId,
  email = "alex@example.com",
  name = "Alex",
  locale = "en",
  roleId = "admin")
Next item
Working with grant-based roles