--- title: "Working with Custom Fields Filters" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Working with Custom Fields Filters} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include = FALSE, purl = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", eval = FALSE, purl = FALSE ) ``` ```{r, purl = FALSE} library(sensortowerR) library(dplyr) ``` ## Introduction Custom Fields Filters are a powerful feature in Sensor Tower that let you create complex, reusable queries to segment apps across hundreds of attributes. In `sensortowerR` 1.0.0, every filter is built with a single verb — `st_filter()` — which returns an S3 object accepted anywhere a raw filter ID string was accepted before. ## Understanding Custom Fields Sensor Tower tracks over 400 custom fields, including: - **Game attributes**: Genre, sub-genre, art style, camera POV - **Monetization**: Free/paid, IAP, ads, subscriptions - **Technical**: SDKs used, platform support, device compatibility - **Performance**: Retention rates, ratings, download counts - **Metadata**: Release dates, publisher info, update frequency ## Basic workflow ### 1. Discover available fields ```{r, purl = FALSE} # List every custom field you can filter on fields <- st_discover_fields() # See valid values for a specific field st_custom_fields_values("Primary Genre") ``` ### 2. Build a filter ```{r, purl = FALSE} # Single-criterion filter puzzle_filter <- st_filter(genre = "Puzzle") # Multi-criterion filter (all AND-combined) word_puzzle_free <- st_filter( genre = c("Puzzle", "Word"), monetization = "Free" ) # Date range new_releases <- st_filter( date_from = Sys.Date() - 90, date_to = Sys.Date() ) # SDK filter unity_games <- st_filter(sdk = "Unity") # Publisher filter ea_games <- st_filter(publisher = "Electronic Arts") ``` ### 3. Inspect the filter ```{r, purl = FALSE} print(puzzle_filter) as.character(puzzle_filter) # Server-side filter ID ``` ### 4. Use the filter Every function that accepts a filter takes either a raw 24-hex ID string or an `st_filter` object: ```{r, purl = FALSE} # Discover apps matching the filter puzzle_apps <- st_apps(filter = puzzle_filter, limit = 100) # Top-chart rankings restricted to the filter top_puzzle <- st_rankings( entity = "app", os = "unified", filter = puzzle_filter, limit = 25 ) # Raw list of filtered apps (power-user) raw_hits <- st_get_filtered_apps(filter = puzzle_filter) ``` ### 5. Combine filters Two `st_filter` objects compose with `c()`: ```{r, purl = FALSE} rpgs <- st_filter(genre = "RPG") free_apps <- st_filter(monetization = "Free") free_rpgs <- c(rpgs, free_apps) apps <- st_apps(filter = free_rpgs) ``` ### 6. Reuse an existing filter ID If you already have a filter ID from the web UI or a previous session: ```{r, purl = FALSE} existing <- st_filter(filter_id = "5ba4585f539ce75b97db6bcb") st_apps(filter = existing) ``` ## Advanced: arbitrary custom fields For fields not covered by the named arguments, use `custom_fields = list(...)`: ```{r, purl = FALSE} complex_filter <- st_filter( custom_fields = list( "Art Style" = "3D", "Player Count" = "Multiplayer", "Primary Genre" = "Shooter" ) ) top_shooters <- st_rankings( entity = "app", os = "ios", filter = complex_filter, limit = 50 ) ``` ## Inspecting and validating filters ```{r, purl = FALSE} # Does a string look like a valid filter ID? st_is_valid_filter_id("5ba4585f539ce75b97db6bcb") # TRUE # Fetch the canonical filter definition from the API collection <- st_get_filter_collection("5ba4585f539ce75b97db6bcb") # Run a smoke-test that the filter yields results st_test_filter("5ba4585f539ce75b97db6bcb") # Richer diagnostic output st_analyze_filter("5ba4585f539ce75b97db6bcb", verbose = TRUE) ``` ## Migration from 0.9.x If you were using `st_filter_by_date()`, `st_filter_by_genre()`, `st_custom_fields_filter()`, `st_combine_filters()`, etc. — all of those are now `.Defunct()` stubs that point at the correct `st_filter()` call: ```{r, purl = FALSE} # Old (0.9.x) # puzzle <- st_filter_by_genre(genres = "Puzzle") # decade <- st_filter_by_date(start_date = "2020-01-01", end_date = "2029-12-31") # combined <- st_combine_filters(list(puzzle, decade)) # New (1.0.0) puzzle <- st_filter(genre = "Puzzle") decade <- st_filter(date_from = "2020-01-01", date_to = "2029-12-31") combined <- c(puzzle, decade) ``` See `vignette("migrating-to-1.0", package = "sensortowerR")` for the complete translation table.