MyNixOS website logo
Description

Tools for Cleaning High-Frequency Real-Time Location Tracking Data.

Provides data cleaning and preprocessing tools for high-frequency positional data from real-time location tracking systems (UWB, RFID, and similar technologies), with functions for ID mapping, time period marking, data standardization, and two-phase conditional gap interpolation. See Bilevicius (2026) <doi:10.5281/zenodo.20783488>.

trackclean

Tools for cleaning high-frequency real-time location tracking data.

trackclean was developed to process data from playground movement research, but applies to any study collecting high-frequency positional data from people moving within a defined space — classrooms, sports facilities, rehabilitation settings, and similar environments.

Installation

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

# Or install the development version from GitHub
# install.packages("devtools")
devtools::install_github("tomasbil/trackclean")

Example Data

The package includes a small example dataset that can be used to trial the full pipeline without any real data. It simulates 10 children tracked during a school recess on a 40m × 60m playground using a UWB positioning system.

library(trackclean)
library(readr)

raw_data   <- read_csv(system.file("extdata", "raw_tracking_data.csv", package = "trackclean"))
id_mapping <- system.file("extdata", "id_mapping.csv", package = "trackclean")

The example dataset includes:

  • 10 participants with raw tag IDs 1–10, mapped to child IDs 5001–5010
  • ~13.5 minutes of data (11:45:00–11:58:30), with observations both inside and outside the analysis window
  • Sub-second timestamps causing multiple readings per second — handled by standardize_to_seconds()
  • Randomly dropped seconds creating gaps — handled by interpolate_gaps()
  • One tag replacement: participant 5003 starts on raw tag ID 3, which is swapped to raw tag ID 11 at 11:51:00 — handled by fix_tag_replacement()

Analysis parameters for this dataset:

ParameterValue
analyze_start"2025-03-18 11:47:00"
analyze_end"2025-03-18 11:57:00"
bell_start"2025-03-18 11:53:00"
bell_end"2025-03-18 11:58:00"
Tag replacementraw_id 3 → raw_id 11 at "2025-03-18 11:51:00"

Expected input format

Raw tracking data (raw_tracking_data.csv):

IDAtXY
12025-03-18 11:45:00.005.00010.000
12025-03-18 11:45:01.005.38310.239
12025-03-18 11:45:01.475.34110.261
...
  • ID: raw tag ID as assigned by the tracking system
  • At: timestamp (POSIXct-readable, sub-second precision supported)
  • X, Y: position in meters

ID mapping (id_mapping.csv):

raw_idchild_id
15001
35003
115003
...
  • raw_id: tag ID as it appears in the raw data
  • child_id: standardized participant ID to use in analysis
  • A participant with a replaced tag appears twice (one row per tag, same child_id)

Quick Start

Optional: Fix Tag Replacements

If a participant's tag was replaced during data collection, run this before the main pipeline:

raw_data <- fix_tag_replacement(
  data = raw_data,
  original_id = 3,
  replacement_id = 11,
  replacement_time = "2025-03-18 11:51:00"
)

This will:

  • Keep observations from tag 3 before 11:51
  • Rename tag 11 observations from 11:51 onwards to tag 3
  • Remove tag 3 observations from 11:51 onwards (duplicate/invalid)
  • Remove tag 11 observations before 11:51 (not yet attached)

1. Prepare Your ID Mapping

Create a CSV file with two columns mapping raw device IDs to your participant IDs:

raw_id,child_id
1,5001
2,5002
3,5003

Or use the bundled example file:

id_mapping <- system.file("extdata", "id_mapping.csv", package = "trackclean")

2. Run the Complete Pipeline

library(trackclean)
library(readr)

raw_data <- read_csv(system.file("extdata", "raw_tracking_data.csv", package = "trackclean"))

# Fix tag replacement first (if applicable)
raw_data <- fix_tag_replacement(
  data = raw_data,
  original_id = 3,
  replacement_id = 11,
  replacement_time = "2025-03-18 11:51:00"
)

cleaned_data <- clean_playground_data(
  data = raw_data,
  id_mapping = system.file("extdata", "id_mapping.csv", package = "trackclean"),
  analyze_start = "2025-03-18 11:47:00",
  analyze_end   = "2025-03-18 11:57:00",
  bell_start    = "2025-03-18 11:53:00",
  bell_end      = "2025-03-18 11:58:00",
  output_file   = "cleaned_data.csv"
)

3. Use Individual Functions

For more control, run each step separately:

# Step 1: Map IDs
data <- map_ids(raw_data, id_mapping)

# Step 2: Mark time periods
data <- mark_time_periods(
  data,
  analyze_start = "2025-03-18 11:47:00",
  analyze_end   = "2025-03-18 11:57:00",
  bell_start    = "2025-03-18 11:53:00",
  bell_end      = "2025-03-18 11:58:00"
)

# Step 3: Standardize to seconds
data <- standardize_to_seconds(data)

# Step 4: Interpolate gaps
data <- interpolate_gaps(
  data,
  max_gap_small = 10,
  max_position_change = 0.3
)

Key Features

Two-Phase Gap Interpolation

The package uses a two-phase approach to handle missing data:

Phase 1: Interpolates small gaps (≤10 seconds by default)

  • Uses linear interpolation between known points
  • Appropriate for brief signal losses

Phase 2: Interpolates larger gaps conditionally

  • Only when position change between endpoints is minimal (≤30cm by default)
  • Indicates the participant remained stationary during the gap
  • Prevents false movement estimates for longer signal dropouts

Quality Assurance

All functions provide:

  • Progress messages and summaries
  • Data integrity checks
  • Row count validation
  • Clear flagging of imputed vs. original data

Function Reference

FunctionPurpose
clean_playground_data()Complete pipeline in one call
fix_tag_replacement()Fix tag replacements (run before pipeline)
map_ids()Map raw device IDs to participant IDs
mark_time_periods()Create Analyze and Bell columns
standardize_to_seconds()Aggregate to one-second intervals
interpolate_gaps()Two-phase gap interpolation

Output Columns

The cleaned dataset includes these flags:

  • id_code: Standardized participant ID
  • Analyze: 1 if within analysis period, 0 otherwise
  • Bell: 1 if within bell period, 0 otherwise (if specified)
  • n_entries: Original number of signals in that second
  • standardized: 1 if multiple signals were averaged, 0 otherwise
  • imputed: 1 if row added via phase 1 interpolation
  • imputed_large: 1 if row added via phase 2 interpolation

Parameters

Customizable Thresholds

cleaned_data <- clean_playground_data(
  data = raw_data,
  id_mapping = "id_mapping.csv",
  analyze_start = "2025-03-18 11:47:00",
  analyze_end   = "2025-03-18 11:57:00",
  max_gap_small = 5,             # Phase 1: ≤5 seconds
  max_gap_large = 30,            # Phase 2: ≤30 seconds max
  max_position_change = 0.5      # Phase 2: ≤50cm movement
)

Author

Tomas Bilevicius

License

CC BY 4.0 — you are free to use, share, and adapt this package for any purpose, including commercially, as long as you give appropriate credit to the author.

Metadata

Version

0.1.0

License

Unknown

Platforms (79)

    Darwin
    FreeBSD
    Genode
    GHCJS
    Linux
    MMIXware
    NetBSD
    none
    OpenBSD
    Redox
    Solaris
    uefi
    wasip1
    Windows
Show all
  • aarch64-darwin
  • aarch64-freebsd
  • aarch64-genode
  • aarch64-linux
  • aarch64-netbsd
  • aarch64-none
  • aarch64-uefi
  • aarch64-windows
  • aarch64_be-none
  • arc-linux
  • arm-none
  • armv5tel-linux
  • armv6l-linux
  • armv6l-netbsd
  • armv6l-none
  • armv7a-linux
  • armv7a-netbsd
  • armv7l-linux
  • armv7l-netbsd
  • avr-none
  • i686-cygwin
  • i686-freebsd
  • i686-genode
  • i686-linux
  • i686-netbsd
  • i686-none
  • i686-openbsd
  • i686-windows
  • javascript-ghcjs
  • loongarch64-linux
  • m68k-linux
  • m68k-netbsd
  • m68k-none
  • microblaze-linux
  • microblaze-none
  • microblazeel-linux
  • microblazeel-none
  • mips-linux
  • mips-none
  • mips64-linux
  • mips64-none
  • mips64el-linux
  • mipsel-linux
  • mipsel-netbsd
  • mmix-mmixware
  • msp430-none
  • or1k-none
  • powerpc-linux
  • powerpc-netbsd
  • powerpc-none
  • powerpc64-linux
  • powerpc64le-linux
  • powerpcle-none
  • riscv32-linux
  • riscv32-netbsd
  • riscv32-none
  • riscv64-linux
  • riscv64-netbsd
  • riscv64-none
  • rx-none
  • s390-linux
  • s390-none
  • s390x-linux
  • s390x-none
  • sh4-linux
  • vc4-none
  • wasm32-wasip1
  • wasm64-wasip1
  • x86_64-cygwin
  • x86_64-freebsd
  • x86_64-genode
  • x86_64-linux
  • x86_64-netbsd
  • x86_64-none
  • x86_64-openbsd
  • x86_64-redox
  • x86_64-solaris
  • x86_64-uefi
  • x86_64-windows