diff --git a/DESCRIPTION b/DESCRIPTION index 3d4ac8e..7242899 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: tarflow.iquizoo Title: Setup "targets" Workflows for "iquizoo" Data Processing -Version: 3.10.2 +Version: 3.10.2.9000 Authors@R: c( person("Liang", "Zhang", , "psychelzh@outlook.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0001-9041-1150")), @@ -22,6 +22,7 @@ Imports: cli, data.iquizoo (>= 2024.3.31.2), DBI, + jsonlite, memoise, rlang (>= 1.0.0), stringr, diff --git a/NAMESPACE b/NAMESPACE index c1939fc..602bfd6 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -4,6 +4,7 @@ export(check_source) export(fetch_data) export(fetch_iquizoo) export(fetch_iquizoo_mem) +export(parse_data) export(setup_option_file) export(setup_source) export(setup_templates) diff --git a/NEWS.md b/NEWS.md index 042a9bd..c06f2e1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,9 @@ +# tarflow.iquizoo (development version) + +## Breaking Changes + +* Added `parse_data()`, previously named as `wrangle_data()`. See . + # tarflow.iquizoo 3.10.2 * Fixed compatibility issue with 'data.iquizoo' 2024.03.31-2. diff --git a/R/database.R b/R/database.R index e31669c..8b8dd30 100644 --- a/R/database.R +++ b/R/database.R @@ -127,3 +127,41 @@ fetch_data <- function(project_id, game_id, ..., params = list(project_id, game_id) ) } + +#' Parse Raw Data +#' +#' Raw data fetched from iQuizoo database is stored in json string format. This +#' function is used to parse raw json string data as [data.frame()] and store +#' them in a list column. +#' +#' @param data The raw data. +#' @param col_raw_json The column name storing raw json string data. +#' @param name_raw_parsed The name used to store parsed data. +#' @return A [data.frame] contains the parsed data. +#' @export +parse_data <- function(data, + col_raw_json = "game_data", + name_raw_parsed = "raw_parsed") { + data[[name_raw_parsed]] <- lapply( + data[[col_raw_json]], + parse_raw_json + ) + data[, names(data) != col_raw_json, drop = FALSE] +} + +# helper functions +parse_raw_json <- function(jstr) { + tryCatch( + jsonlite::fromJSON(jstr), + error = function(cnd) { + warn( + c( + "Failed to parse json string:", + conditionMessage(cnd), + i = "Will parse it as `NULL` instead." + ) + ) + return() + } + ) +} diff --git a/R/targets.R b/R/targets.R index d02dd7b..9f204d9 100644 --- a/R/targets.R +++ b/R/targets.R @@ -240,12 +240,11 @@ tar_prep_raw <- function(contents, contents$tar_indices <- syms(sprintf("%s_%s", name_indices, contents$game_id)) list( raw_data_parsed = if ("parse" %in% action_raw_data) { - check_installed("preproc.iquizoo", "becasue required in wrangling.") tarchetypes::tar_eval( targets::tar_target( tar_parsed, - wrangle_data(tar_data), - packages = "preproc.iquizoo" + parse_data(tar_data), + packages = "tarflow.iquizoo" ), contents ) @@ -255,7 +254,12 @@ tar_prep_raw <- function(contents, tarchetypes::tar_eval( targets::tar_target( tar_indices, - preproc_data(tar_parsed, prep_fun, .input = input, .extra = extra), + preproc.iquizoo::preproc_data( + tar_parsed, + prep_fun, + .input = input, + .extra = extra + ), packages = "preproc.iquizoo" ), data.iquizoo::merge_preproc(contents) @@ -271,7 +275,6 @@ objects <- function() { utils::globalVariables( c( "tar_data", "tar_parsed", "tar_indices", - "wrangle_data", "preproc_data", "prep_fun", "input", "extra" ) ) diff --git a/_pkgdown.yml b/_pkgdown.yml index 4ff8f0e..bab4757 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -16,6 +16,7 @@ reference: - fetch_iquizoo - fetch_iquizoo_mem - fetch_data + - parse_data - title: "Miscellaneous Option Functions" desc: Functions to help you set up options. contents: diff --git a/man/parse_data.Rd b/man/parse_data.Rd new file mode 100644 index 0000000..53fdd08 --- /dev/null +++ b/man/parse_data.Rd @@ -0,0 +1,23 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/database.R +\name{parse_data} +\alias{parse_data} +\title{Parse Raw Data} +\usage{ +parse_data(data, col_raw_json = "game_data", name_raw_parsed = "raw_parsed") +} +\arguments{ +\item{data}{The raw data.} + +\item{col_raw_json}{The column name storing raw json string data.} + +\item{name_raw_parsed}{The name used to store parsed data.} +} +\value{ +A \link{data.frame} contains the parsed data. +} +\description{ +Raw data fetched from iQuizoo database is stored in json string format. This +function is used to parse raw json string data as \code{\link[=data.frame]{data.frame()}} and store +them in a list column. +} diff --git a/tests/testthat/test-database.R b/tests/testthat/test-database.R index 7a4911b..ab73c59 100644 --- a/tests/testthat/test-database.R +++ b/tests/testthat/test-database.R @@ -10,3 +10,22 @@ test_that("Ensure source checking works", { check_source(source = source_invalid) |> expect_false() }) + +test_that("`parse_data()` works", { + js_str <- r"([{"a": 1, "b": 2}])" + data <- data.frame(game_data = js_str) + parse_data(data)$raw_parsed[[1]] |> + expect_identical(jsonlite::fromJSON(js_str)) + parse_data(data, name_raw_parsed = "parsed") |> + expect_named("parsed") +}) + +test_that("Can deal with invalid or empty json", { + data_case_invalid <- data.frame(game_data = "[1") + parse_data(data_case_invalid)$raw_parsed[[1]] |> + expect_null() |> + expect_warning("Failed to parse json string") + data_case_empty <- data.frame(game_data = c("[]", "{}")) + parse_data(data_case_empty)$raw_parsed |> + lapply(expect_length, 0) +})