# Get started

First, make sure we load some useful libraries (and of course `mpathsenser` itself).

    library(tidyr)
    library(dplyr)
    #>
    #> Attaching package: 'dplyr'
    #> The following objects are masked from 'package:stats':
    #>
    #>     filter, lag
    #> The following objects are masked from 'package:base':
    #>
    #>     intersect, setdiff, setequal, union
    library(ggplot2)
    library(mpathsenser)

# Importing files

The data for this vignette is contained in the `extdata` folder. However, on some system this folder may be set to read-only and it is generally good practice not to modify package folders (to prevent changing or breaking the package). To this end, we first copy the data to a temporary directory (as defined by the environment variable , , or ), a directory that is freshly created each time at R’s start up and cleaned up when the session ends.

    # Get the temp folder
    tempdir <- tempdir()
    tempdir <- file.path(tempdir, "vignette")
    dir.create(tempdir)

    # Get a handle to the data files
    path <- system.file("extdata", "example", package = "mpathsenser")

    # Get a list of all the files that are to be copied
    copy_list <- list.files(path, "carp-data", full.names = TRUE)

    # Copy all data
    file.copy(
      from = copy_list,
      to = tempdir,
      overwrite = TRUE,
      copy.mode = FALSE
    )

The `extdata` folder contains several `.zip` files as well as some `JSON` files. It is likely that the data for your study will look the same only much more. Note that all of these data files came directly from m-Path Sense (i.e. there was no pre-processing yet).

The data from m-Path Sense originates in the following way: The application continuously collects all kinds of data in the background (e.g. accelerometer data). Once collected, the data goes through several stages where, for example, the data is pre-processed (as already happens with data from the `light` sensor) or anonymised upon request. Finally, data is written to a `JSON` file which is really just a text file but with a specific format. When some new data comes in (whether it be from the same sensor or not), the next line is written in the `JSON` file and so on, until the file has reached a certain size (5MB by default). The `JSON` file is then zipped to reduce its size and subsequently transferred to a server. Once transferred, the data is deleted from the participant’s phone to both save on space as well as prevent data leakage.

Thus, a first step to take is to unzip these files to extract its `JSON` contents. If you feel more comfortable unzipping using your favourite zip program you can do so, just make sure all files end up in the same directory (including the non-zipped JSON files).

    unzip_data(path = tempdir)
    #> Unzipped 37 files.

In m-Path Sense, data is written to JSON files as it comes in. In the JSON file format, every file starts with `[` and ends with `]`. If the app is killed, JSON files are not properly closed and hence cannot be read by JSON parsers. So, we must first test if all files are in a valid JSON format and fix those that are not.

You may first run `fix_jsons()` to fix all files in the directory that need fixing, or you can first run `test_jsons()` to get an estimate of how many file need fixing. Running `fix_jsons()` also runs `test_jsons()` implicitly to only fix files that really need fixing.

    # Note that test_jsons returns the full path names
    to_fix <- test_jsons(tempdir)
    #> Warning: There were issues in some files
    print(to_fix)
    #>  [1] "C:\\Users\\u0134047\\AppData\\Local\\Temp\\Rtmp6L245I\\vignette\\1_example_carp-data-2022-06-14-09-18-41-055229Z.json"
    #>  [2] "C:\\Users\\u0134047\\AppData\\Local\\Temp\\Rtmp6L245I\\vignette\\1_example_carp-data-2022-06-14-09-38-53-504884Z.json"
    #>  [3] "C:\\Users\\u0134047\\AppData\\Local\\Temp\\Rtmp6L245I\\vignette\\1_example_carp-data-2022-06-14-09-55-14-202021Z.json"
    #>  [4] "C:\\Users\\u0134047\\AppData\\Local\\Temp\\Rtmp6L245I\\vignette\\1_example_carp-data-2022-06-14-11-48-39-822128Z.json"
    #>  [5] "C:\\Users\\u0134047\\AppData\\Local\\Temp\\Rtmp6L245I\\vignette\\1_example_carp-data-2022-06-14-12-46-41-739139Z.json"
    #>  [6] "C:\\Users\\u0134047\\AppData\\Local\\Temp\\Rtmp6L245I\\vignette\\1_example_carp-data-2022-06-14-12-51-10-826674Z.json"
    #>  [7] "C:\\Users\\u0134047\\AppData\\Local\\Temp\\Rtmp6L245I\\vignette\\1_example_carp-data-2022-06-14-13-24-42-818906Z.json"
    #>  [8] "C:\\Users\\u0134047\\AppData\\Local\\Temp\\Rtmp6L245I\\vignette\\1_example_carp-data-2022-06-14-17-47-29-568210Z.json"
    #>  [9] "C:\\Users\\u0134047\\AppData\\Local\\Temp\\Rtmp6L245I\\vignette\\1_example_carp-data-2022-06-14-20-35-31-622759Z.json"
    #> [10] "C:\\Users\\u0134047\\AppData\\Local\\Temp\\Rtmp6L245I\\vignette\\1_example_carp-data-2022-06-14-23-47-14-992568Z.json"
    #> [11] "C:\\Users\\u0134047\\AppData\\Local\\Temp\\Rtmp6L245I\\vignette\\1_example_carp-data-2022-06-15-06-59-54-808885Z.json"
    #> [12] "C:\\Users\\u0134047\\AppData\\Local\\Temp\\Rtmp6L245I\\vignette\\1_example_carp-data-2022-06-15-08-03-14-431352Z.json"

    fix_jsons(path = NULL, to_fix)
    #> Fixed 12 files

Next, we can create an `mpathsenser` database using the `create_db()` function. This function takes as a first argument a pathname where the database will be created and as a second argument a `db_name` to name the database file. You may also leave `path` set to `NULL` and specify a full path name (including file name) in the `db_name` argument. Always remember to save the output to a variable so you can use it later and to avoid having an open handle but unused handle on the database connection.

    # Create a new database
    db <- create_db(tempdir, "getstarted.db")

Finally, we can import the data into the newly created database using the `import()` function. This function takes as a first argument the path to the directory where the data is located and as a second argument the database handle. You may also specify a `batch_size` to control how many files are imported at once. Files are processed sequentially (though parallellism is supported via the `future` package) but files are written in batch to the database for the sake of efficiency. A greater batch size thus denotes larger batches of files being written to the database at once (and is more efficient), but risk failing the larger batch a single file fails to be processed.

    # Import the data
    import(
      path = tempdir,
      db = db,
      sensors = NULL, # All sensors
      batch_size = 12,
      recursive = TRUE
    )
    #> All files were successfully written to the database.

# Creating a coverage chart

To get a better overview of the data, we may create a coverage chart that shows the average number of collected samples per hour for each sensor for a single participant. An important distinction must be made between a relative and absolute coverage chart. The relative coverage chart shows the average number of samples per hour for each sensor as a percentage of the expected number of samples per hour for that sensor. The absolute coverage chart shows the average number of samples per hour for each sensor. The relative coverage chart is useful to see how well the data is being collected for each sensor, while the absolute coverage chart is useful to see how well the data is being collected in general.

    sensors <- c(
      "Accelerometer", "Activity", "AppUsage", "Bluetooth", "Calendar",
      "Connectivity", "Device", "Gyroscope", "InstalledApps", "Light",
      "Location", "Memory", "Pedometer", "Screen", "Weather", "Wifi"
    )
    cov <- coverage(
      db = db,
      participant_id = "2784",
      sensor = sensors,
      relative = FALSE
    )

    print(cov)
    #> # A tibble: 384 × 3
    #>     hour measure       coverage
    #>    <dbl> <fct>            <dbl>
    #>  1     0 Accelerometer        0
    #>  2     1 Accelerometer        0
    #>  3     2 Accelerometer        0
    #>  4     3 Accelerometer        0
    #>  5     4 Accelerometer        0
    #>  6     5 Accelerometer        0
    #>  7     6 Accelerometer        0
    #>  8     7 Accelerometer     1528
    #>  9     8 Accelerometer      540
    #> 10     9 Accelerometer     6496
    #> # ℹ 374 more rows

Additionally, we can print the coverage data using the `plot()` function.

    plot(cov)

# Closing the database

Finally, recall that once you’re done working with a database to also close it.

    close_db(db)