diff --git a/NAMESPACE b/NAMESPACE index 092369c..2fa77d9 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -17,9 +17,8 @@ export(gap_handler) export(gapless_Datetimes) export(gg_day) export(gg_overview) -export(import.ActLumus) +export(import) export(import.Dataset) -export(import.LYS) export(import.Statechanges) export(interval2state) export(join.datasets) diff --git a/NEWS.md b/NEWS.md index d62f48b..383ca0c 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,7 @@ # LightLogR 0.2.1.9000 +* Reworked the internals of the light logger data import functions. They now use a more straightforward function factory approach. For users the only visible change it that device specific functions now have the form `import$device()` instead of the old `import.device()`. + * Added the `symlog_trans()` function from a [post on stack overflow](https://stackoverflow.com/a/14674703). This function leads to a better visualization of light logger data, as a logarithmic transformation is necessary, but values of 0 are common. The function was integrated as a default for `gg_day()` and will likely be the basis of upcoming visualization functions. * Added the `aggregate_Datetime()` function to aggregate data to a given time interval. diff --git a/R/aaa.r b/R/aaa.r index 0b4f14f..14e55c2 100644 --- a/R/aaa.r +++ b/R/aaa.r @@ -1,4 +1,4 @@ -Time <- mEDI <- Time.data <- Datetime <- timestamp <- tz <- Day.data <- `DATE/TIME` <- n <- Datetime.rounded <- id <- sleep.colname.string <- file.name <- Interval <- original.datapoints.fleeting <- MEDI <- State.Brown <- Reference <- Reference.check <- Id <- Start.date.shift <- data <- Shift <- `MELANOPIC EDI` <- State <- group <- End <- Start <- Quant.x <- Quant.y <- is.implicit <- group.indices <- Id2 <- gap.id <- start <- end <- NULL +Time <- mEDI <- Time.data <- Datetime <- timestamp <- tz <- Day.data <- `DATE/TIME` <- n <- Datetime.rounded <- id <- sleep.colname.string <- file.name <- Interval <- original.datapoints.fleeting <- MEDI <- State.Brown <- Reference <- Reference.check <- Id <- Start.date.shift <- data <- Shift <- `MELANOPIC EDI` <- State <- group <- End <- Start <- Quant.x <- Quant.y <- is.implicit <- group.indices <- Id2 <- gap.id <- start <- end <- path <- auto.id <- n_max <- manual.id <- NULL empty_function <- function() { rsconnect::accountInfo() diff --git a/R/data.r b/R/data.r index 0c36ad8..74037bf 100644 --- a/R/data.r +++ b/R/data.r @@ -22,6 +22,11 @@ #' A vector of all supported devices for import functions #' +#' These are all supported devices where there is a dedicated import function. +#' Import functions can be called either through [import.Dataset()] with the +#' respective `device = "device"` argument, or directly, e.g., +#' `import$ActLumus()`. +#' #' @format `supported.devices` A character vector, listing all supported devices #' \describe{ #' \item{suppored.devices}{strings} diff --git a/R/import_LL.R b/R/import_LL.R index 3b5370d..28a1e8f 100644 --- a/R/import_LL.R +++ b/R/import_LL.R @@ -2,33 +2,44 @@ #' Import a light logger dataset or related data #' +#' @description +#' #' Imports a dataset and does the necessary transformations to get the right #' column formats. Unless specified otherwise, the function will set the #' timezone of the data to `UTC`. It will also enforce an `id` to separate #' different datasets and will order/arrange the dataset within each `id`. #' -#' If the `Id` column is already part of the `dataset` it will just use this -#' column. If the column is not present it will add this column and fill it with -#' the filename of the importfile (see param `auto.id`). +#' There are specific and a general import function. The general import function +#' is described below, whereas the specific import functions take the form of +#' `import$device()`. The general import function is a thin wrapper around the +#' specific import functions. The specific import functions take the following +#' arguments: +#' +#' * `filename`: Filename(s) for the Dataset. Can also contain the filepath, +#' but `path` must then be `NULL`. Expects a `character`. If the vector is +#' longer than `1`, multiple files will be read in into one Tibble. +#' * `path`: Optional path for the dataset(s). `NULL` is the default. Expects +#' a `character`. +#' * `n_max`: maximum number of lines to read. Default is `Inf`. +#' * `tz`: Timezone of the data. `"UTC"` is the default. Expects a +#' `character`. You can look up the supported timezones with [OlsonNames()]. +#' * `ID.colname`: Lets you specify a column for the participant id. Expects a +#' symbol (Default is `Id`). This column will be used for grouping +#' ([dplyr::group_by()]). +#' * `auto.id`: If the `Id.colname` column is added to the `dataset`, the `Id` +#' can be automatically extracted from the filename. The argument expects a +#' regular expression [regex] and will by default just give the whole filename +#' without file extension. +#' * `manual.id`: If this argument is not `NULL`, and no `ID` column is part +#' of the `dataset`, this `character` scalar will be used. **Don´t use this +#' argument if multiple files from different participants are used!** +#' * `locale`: The locale controls defaults that vary from place to place. +#' * `...`: supply additional arguments to the [readr] import functions, like `na`. Might also be used to supply arguments to the specific import functions, like `column_names` for `Actiwatch_Spectrum` devices. Those devices will alway throw a helpful error message if you forget to supply the necessary arguments. +#' +#' @details If the `Id` column is already part of the `dataset` it will just use +#' this column. If the column is not present it will add this column and fill +#' it with the filename of the importfile (see param `auto.id`). #' -#' @param filename Filename(s) for the Dataset. Can also contain the filepath, -#' but `path` must then be `NULL`. Expects a `character`. If the vector is -#' longer than `1`, multiple files will be read in into one Tibble. -#' @param path Optional path for the dataset(s). `NULL` is the default. Expects -#' a `character`. -#' @param n_max maximum number of lines to read. Default is `Inf`. -#' @param tz Timezone of the data. `"UTC"` is the default. Expects a -#' `character`. You can look up the supported timezones with [OlsonNames()]. -#' @param ID.colname Lets you specify a column for the participant id. Expects a -#' symbol (Default is `Id`). This column will be used for grouping -#' ([dplyr::group_by()]). -#' @param auto.id If the `Id.colname` column is added to the `dataset`, the `Id` -#' can be automatically extracted from the filename. The argument expects a -#' regular expression [regex] and will by default just give the whole filename -#' without file extension. -#' @param manual.id If this argument is not `NULL`, and no `ID` column is part -#' of the `dataset`, this `character` scalar will be used. -#' **Don´t use this argument if multiple files from different participants are used!**. #' @param ... Parameters that get handed down to the specific import functions #' @param device From what device do you want to import? For every supported #' device, there is a sample data file that you can use to test the function @@ -36,6 +47,7 @@ #' by the `device.ext` spec to access the sample file): #' * `"ActLumus"` (ActLumus.txt) #' * `"LYS"` (LYS.csv) +#' * `"Actiwatch_Spectrum"` (Actiwatch.csv) *Note: as the `locale` argument use `readr::locale(encoding="latin1")` . This is due to the fact that the German Actiwatch software from which this sample file was taken, uses a different encoding than UTF-8.* #' @importFrom rlang := #' @return Tibble/Dataframe with a POSIXct column for the datetime #' @export @@ -68,12 +80,12 @@ #' #' ```{r} #' filepath <- system.file("extdata/sample_data_ActLumus.txt", package = "LightLogR") -#' dataset <- import.ActLumus(filepath) +#' dataset <- import$ActLumus(filepath) #' ``` #' #' ```{r} #' dataset %>% -#' dplyr::select(Datetime, TEMPERATURE, LIGHT, MEDI) %>% +#' dplyr::select(Datetime, TEMPERATURE, LIGHT, MEDI, Id) %>% #' dplyr::slice(1500:1505) %>% #' flextable::flextable() %>% #' flextable::autofit() @@ -87,89 +99,172 @@ import.Dataset <- function(device, ...) { device %in% supported.devices ) - import_function_expr <- rlang::parse_expr(paste0("import.", device)) + import_function_expr <- rlang::parse_expr(paste0("import$", device)) eval(import_function_expr)(...) } -# ActLumus ---------------------------------------------------------------- - -#' Import Dataset from ActLumus -#' -#' @rdname import.Dataset -#' @export - -import.ActLumus <- - function(filename, - path = NULL, - n_max = Inf, - tz = "UTC", - ID.colname = Id, - auto.id = ".*", - manual.id = NULL) { - - if (!is.null(path)) { - filename <- file.path(path, filename) - } - - #special handling for ActLumus files - import.expr <- rlang::expr( - {tmp <- readr::read_delim(!!filename, - skip = 32, - delim = ";", - n_max = !!n_max, - col_types = paste0("c",rep("d",32)), - id = "file.name" +# General ---------------------------------------------------------------- +#This internal helper function is a function factory to create import functions +#based on device name and specific import expression +imports <- function(device, + import.expr) { + + import.expr <- rlang::enexpr(import.expr) + ID.colname <- quote({{ ID.colname}}) + + rlang::new_function( + #function arguments + rlang::exprs( + filename =, + path = NULL, + n_max = Inf, + tz = "UTC", + ID.colname = Id, + auto.id = ".*", + manual.id = NULL, + locale = readr::default_locale(), + ... = + ), + #function expression + rlang::expr({ + + if (!is.null(path)) { + filename <- file.path(path, filename) + } + + id.colname.defused <- colname.defused(!!ID.colname) + #initial checks + stopifnot( + "filename needs to be a character (vector)" = is.character(filename), + "device needs to be a character" = is.character(!!device), + "tz needs to be a character" = is.character(tz), + "tz needs to be a valid time zone, see `OlsonNames()`" = tz %in% OlsonNames(), + "auto.id needs to be a string" = is.character(auto.id), + "n_max needs to be a positive numeric" = is.numeric(n_max) ) - tmp <- tmp %>% - dplyr::rename(Datetime = `DATE/TIME`, - MEDI = `MELANOPIC EDI`) %>% - dplyr::mutate(Datetime = - Datetime %>% lubridate::dmy_hms(tz = !!tz)) + #import the file + tmp <- rlang::eval_tidy(!!import.expr) + + #validate/manipulate the file + if(!id.colname.defused %in% names(tmp)) { + switch(is.null(manual.id) %>% as.character(), + "TRUE" = + {tmp <- tmp %>% + dplyr::mutate(!!ID.colname := + basename(file.name) %>% + tools::file_path_sans_ext() %>% + stringr::str_extract(auto.id), + .before = 1)}, + "FALSE" = + {tmp <- tmp %>% + dplyr::mutate(!!ID.colname := manual.id, .before = 1)} + ) } + tmp <- tmp %>% + dplyr::mutate(file.name = basename(file.name) %>% + tools::file_path_sans_ext(), + !!ID.colname := factor(!!ID.colname)) %>% + dplyr::group_by(!!ID.colname) %>% + dplyr::arrange(Datetime, .by_group = TRUE) + + #give info about the file + import.info(tmp, !!device, tz, !!ID.colname) + + #return the file + tmp + + }), + rlang::caller_env() + ) +} + +import_arguments <- list( + #ActLumus + ActLumus = rlang::expr({ + tmp <- readr::read_delim( + filename, + skip = 32, + delim = ";", + n_max = n_max, + col_types = paste0("c", rep("d", 32)), + id = "file.name", + locale = locale, + ... + ) + tmp <- tmp %>% + dplyr::rename(Datetime = `DATE/TIME`, + MEDI = `MELANOPIC EDI`) %>% + dplyr::mutate(Datetime = + Datetime %>% lubridate::dmy_hms(tz = tz)) + }), + #LYS + LYS = rlang::expr({ + tmp <- readr::read_csv(filename, + n_max = n_max, + col_types = c("cfddddddddddd"), + id = "file.name", + locale = locale, + ... ) - - #generic import function - import.link("ActLumus", {{ ID.colname }}) - - } + tmp <- tmp %>% + dplyr::rename(Datetime = timestamp, + MEDI = mEDI) %>% + dplyr::mutate(Datetime = + Datetime %>% lubridate::dmy_hms(tz = tz)) + }), + #Actiwatch Spectrum + Actiwatch_Spectrum = rlang::expr({ + #separate the dots list in the column_names and the rest + dots <- rlang::list2(...) + column_names <- dots$column_names + if(is.null(column_names)) + stop("Actiwatch Spectrum requires a vector of `column_names` in the order in which they appear in the file in order to properly detect the starting row") + dots$column_names <- NULL + tmp <- + purrr::map( + filename, + \(x) { + rows_to_skip <- detect_starting_row(x, + locale = locale, + column_names = column_names, + n_max = n_max) + df <- suppressMessages(do.call( + readr::read_csv, + append(list( + x, + skip = rows_to_skip, + locale=locale, + id = "file.name", + show_col_types = FALSE + ), + dots))) + + df %>% + dplyr::select(!dplyr::starts_with("...")) + + }) %>% purrr::list_rbind() + tmp <- tmp %>% + tidyr::unite(col = "Datetime", + tidyselect::where(lubridate::is.Date), + tidyselect::where(hms::is_hms), + remove = FALSE + ) %>% + dplyr::mutate( + Datetime = lubridate::ymd_hms(Datetime), + dplyr::across( + dplyr::where(is.character) & + dplyr::where(~ any(stringr::str_detect(.x, ","), na.rm = TRUE)), + ~ stringr::str_replace(.x, ",", ".") %>% + as.numeric() + )) + }) -# LYS --------------------------------------------------------------------- +) -#' Import Dataset from LYS Button +#' Import Datasets from supported devices #' #' @rdname import.Dataset #' @export - -import.LYS <- function(filename, - path = NULL, - n_max = Inf, - tz = "UTC", - ID.colname = Id, - auto.id = ".*", - manual.id = NULL) { - - if (!is.null(path)) { - filename <- file.path(path, filename) - } - - #special handling for LYS files - import.expr <- rlang::expr( - {tmp <- readr::read_csv(!!filename, - n_max = !!n_max, - col_types = c("cfddddddddddd"), - id = "file.name" - ) - tmp <- tmp %>% - dplyr::rename(Datetime = timestamp, - MEDI = mEDI) %>% - dplyr::mutate(Datetime = - Datetime %>% lubridate::dmy_hms(tz = !!tz)) - } - ) - - #generic import function - import.link("LYS", {{ ID.colname }}) - -} +import <- purrr::imap(import_arguments, \(x, idx) imports(idx,x)) diff --git a/R/import_States.R b/R/import_States.R index e24bf68..7eb7671 100644 --- a/R/import_States.R +++ b/R/import_States.R @@ -8,7 +8,13 @@ #' * In the `wide` format, multiple `Datetime` columns indicate the state through the column name. These get pivoted to the `long` format and can be recoded through the `State.encoding` argument. #' * In the `long` format, one column indicates the `State`, while the other gives the `Datetime`. #' -#' @inheritParams import.Dataset +#' @param filename Filename(s) for the Dataset. Can also contain the filepath, +#' but `path` must then be `NULL`. Expects a `character`. If the vector is +#' longer than `1`, multiple files will be read in into one Tibble. +#' @param path Optional path for the dataset(s). `NULL` is the default. Expects +#' a `character`. +#' @param tz Timezone of the data. `"UTC"` is the default. Expects a +#' `character`. You can look up the supported timezones with [OlsonNames()]. #' @param sep String that separates columns in the import file. Defaults to #' `","`. #' @param dec String that indicates a decimal separator in the import file. diff --git a/R/import_helper.r b/R/import_helper.r index b989cc3..310a5c7 100644 --- a/R/import_helper.r +++ b/R/import_helper.r @@ -1,58 +1,3 @@ -#This internal helper function is used for setup of imports of various device files -import.LL <- function(filename, - device = "none", - import.expr, - n_max = Inf, - tz = "UTC", - ID.colname = Id, - auto.id = ".*", - manual.id = NULL) { - - id.colname.defused <- colname.defused(id) - tz <- tz - - #initial checks - stopifnot( - "filename needs to be a character (vector)" = is.character(filename), - "device needs to be a character" = is.character(device), - "tz needs to be a character" = is.character(tz), - "tz needs to be a valid time zone, see `OlsonNames()`" = tz %in% OlsonNames(), - "auto.id needs to be a string" = is.character(auto.id), - "n_max needs to be a positive numeric" = is.numeric(n_max) - ) - #import the file - tmp <- rlang::eval_tidy(import.expr) - - #validate/manipulate the file - if(!id.colname.defused %in% names(tmp)) { - switch(is.null(manual.id) %>% as.character(), - "TRUE" = - {tmp <- tmp %>% - dplyr::mutate({{ ID.colname }} := - basename(file.name) %>% - tools::file_path_sans_ext() %>% - stringr::str_extract(auto.id), - .before = 1)}, - "FALSE" = - {tmp <- tmp %>% - dplyr::mutate({{ ID.colname }} := manual.id, .before = 1)} - ) - } - tmp <- tmp %>% - dplyr::mutate(file.name = basename(file.name) %>% - tools::file_path_sans_ext(), - {{ ID.colname }} := factor({{ ID.colname }})) %>% - dplyr::group_by({{ ID.colname }}) %>% - dplyr::arrange(Datetime, .by_group = TRUE) - - #give info about the file - import.info(tmp, device, tz, {{ ID.colname }}) - - #return the file - tmp -} - - #This internal helper function prints basic information about a dataset and is used for import function import.info <- function(tmp, device, tz, ID.colname) { #give info about the file @@ -87,26 +32,43 @@ import.info <- function(tmp, device, tz, ID.colname) { utils::capture.output(interval.time)[c(-1,-2,-4)] %>% cat(sep = "\n") } -#This internal helper functions provides a link from the specific import function to the generic import function - -import.link <- function(device, ID.colname) { +#This internal helper function looks for the starting row of an import file based on a vector of column names in order. +detect_starting_row <- + function(filepath, + locale = readr::default_locale(), + column_names, + n_max = 250) { + + #make a regex pattern from the column names + column_names <- + column_names %>% + stringr::str_flatten(collapse = ".*") + + #read in all the lines and remove junk + line_read <- + readr::read_lines(filepath, n_max = n_max, locale=locale) - env <- parent.frame() - filename <- env$filename - tz<- env$tz - auto.id<- env$auto.id - manual.id <- env$manual.id - n_max<- env$n_max - path<- env$path - import.expr <- env$import.expr + #find the row where the column names are + which_lines <- + line_read %>% + purrr::map_vec( + \(x) stringr::str_detect(x,column_names) + ) %>% which() + + #if there is no line with the column names, return an error + if(length(which_lines) == 0) { + stop("Could not find a line with this order of column names in the file. Please check the correct order and spelling of the given columns.") + } + + #if there is more than one line with the column names, return an error + if(length(which_lines) > 1) { + stop(paste("Found", length(which_lines), "lines with the given column names, but require exactly 1. Please provide a more specific pattern.")) + } + + #if there is only one line with the column names, return the line number + #and reduce it by one to get the lines to skip + if(length(which_lines) == 1) { + return(which_lines-1) + } - #generic import function - import.LL(filename = filename, - device = device, - import.expr = import.expr, - n_max = n_max, - tz = tz, - manual.id = manual.id, - ID.colname = {{ ID.colname }}, - auto.id = auto.id) } \ No newline at end of file diff --git a/R/join.R b/R/join.R index 649da79..75e8726 100644 --- a/R/join.R +++ b/R/join.R @@ -17,8 +17,8 @@ #' package = "LightLogR") #' file.LL <- "205_actlumus_Log_1020_20230904101707532.txt.zip" #' file.env <- "cyepiamb_CW35_Log_1431_20230904081953614.txt.zip" -#' dataset.LL <- import.ActLumus(file.LL, path, auto.id = "^(\\d{3})") -#' dataset.env <- import.ActLumus(file.env, path, manual.id = "CW35") +#' dataset.LL <- import$ActLumus(file.LL, path, auto.id = "^(\\d{3})") +#' dataset.env <- import$ActLumus(file.env, path, manual.id = "CW35") #' #' #join the datasets #' joined <- join.datasets(dataset.LL, dataset.env) diff --git a/R/shiny_import.R b/R/shiny_import.R index f96ac35..fda4d87 100644 --- a/R/shiny_import.R +++ b/R/shiny_import.R @@ -15,8 +15,8 @@ server <- function(input, output) { writeLines(lines, temp_file) read_methods <- list( - LYS = import.LYS, - ActLumus = import.ActLumus, + LYS = import$LYS, + ActLumus = import$ActLumus, read_csv = function(x) readr::read_csv(x) ) diff --git a/README.Rmd b/README.Rmd index 0ed631b..9d14770 100644 --- a/README.Rmd +++ b/README.Rmd @@ -71,7 +71,7 @@ You can import a light logger dataset with ease. The import functions give quick ```{r, out.width="50%", fig.align='center'} filename <- system.file("extdata/sample_data_LYS.csv", package = "LightLogR") -dataset <- import.LYS(filename, tz = "Europe/Berlin") +dataset <- import$LYS(filename, tz = "Europe/Berlin") dataset %>% select(Datetime, lux, kelvin, MEDI) %>% slice(8000:8005) %>% flextable() %>% autofit() @@ -81,6 +81,7 @@ dataset %>% select(Datetime, lux, kelvin, MEDI) %>% slice(8000:8005) %>% Once imported, **LightLogR** allows you conveniently visualize the data. ```{r, fig.retina=2} +dataset %>% gg_overview() dataset %>% gg_day() ``` @@ -88,7 +89,8 @@ There is a wide range of options to the `gg_day()` function to customize the out ```{r, fig.retina=2} dataset %>% - gg_day(col = MEDI >= 250, scales = "fixed", size = 0.5) + + gg_day( + col = MEDI >= 250, scales = "fixed", size = 0.5) + scale_color_discrete(type = c("orange", "skyblue")) ``` diff --git a/README.md b/README.md index 31e2d85..7815636 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ give quick, helpful feedback about the dataset. ``` r filename <- system.file("extdata/sample_data_LYS.csv", package = "LightLogR") -dataset <- import.LYS(filename, tz = "Europe/Berlin") +dataset <- import$LYS(filename, tz = "Europe/Berlin") #> Successfully read in 11422 observations from LYS-file #> Timezone set is Europe/Berlin. #> Start: 2023-06-21 00:00:12 @@ -107,12 +107,17 @@ dataset %>% select(Datetime, lux, kelvin, MEDI) %>% slice(8000:8005) %>% Once imported, **LightLogR** allows you conveniently visualize the data. ``` r -dataset %>% gg_day() -#> Warning: Transformation introduced infinite values in continuous y-axis +dataset %>% gg_overview() ``` +``` r +dataset %>% gg_day() +``` + + + There is a wide range of options to the `gg_day()` function to customize the output. Have a look at the reference page (`?gg_day`) to see all options. You can also override most of the defaults, e.g., for different @@ -120,11 +125,11 @@ options. You can also override most of the defaults, e.g., for different ``` r dataset %>% - gg_day(col = MEDI >= 250, scales = "fixed", size = 0.5) + + gg_day( + col = MEDI >= 250, scales = "fixed", size = 0.5) + scale_color_discrete(type = c("orange", "skyblue")) #> Scale for colour is already present. #> Adding another scale for colour, which will replace the existing scale. -#> Warning: Transformation introduced infinite values in continuous y-axis ``` @@ -146,7 +151,6 @@ sample.data.environment %>% scales = "fixed", geom = "line") #> Only Dates will be used from start.date and end.date input. If you also want to set Datetimes or Times, consider using the `filter_Datetime()` function instead. -#> Warning: Transformation introduced infinite values in continuous y-axis ``` With @@ -172,8 +176,6 @@ sample.data.environment %>% group = interaction(Source, Datetime.rounded)) + theme(legend.position = "bottom") #> Only Dates will be used from start.date and end.date input. If you also want to set Datetimes or Times, consider using the `filter_Datetime()` function instead. -#> Warning: Transformation introduced infinite values in continuous y-axis -#> Warning: Removed 3429 rows containing non-finite values (`stat_boxplot()`). ``` diff --git a/_pkgdown.yml b/_pkgdown.yml index ed955f4..4cac854 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -12,8 +12,7 @@ reference: through `import.*()`. contents: - import.Dataset - - import.ActLumus - - import.LYS + - import - import.Statechanges - title: Process diff --git a/data-raw/supported-devices.R b/data-raw/supported-devices.R index e649d5b..8344bea 100644 --- a/data-raw/supported-devices.R +++ b/data-raw/supported-devices.R @@ -1,5 +1,6 @@ ## code to prepare `supported.devices` dataset goes here -supported.devices <- c("LYS", "ActLumus") +library(LightLogR) +supported.devices <- names(import_arguments) usethis::use_data(supported.devices, overwrite = TRUE) diff --git a/data/supported.devices.rda b/data/supported.devices.rda index 0cab54b..4f40719 100644 Binary files a/data/supported.devices.rda and b/data/supported.devices.rda differ diff --git a/man/figures/README-unnamed-chunk-4-1.png b/man/figures/README-unnamed-chunk-4-1.png index 61ac955..083cfb4 100644 Binary files a/man/figures/README-unnamed-chunk-4-1.png and b/man/figures/README-unnamed-chunk-4-1.png differ diff --git a/man/figures/README-unnamed-chunk-4-2.png b/man/figures/README-unnamed-chunk-4-2.png new file mode 100644 index 0000000..d4b85dd Binary files /dev/null and b/man/figures/README-unnamed-chunk-4-2.png differ diff --git a/man/figures/README-unnamed-chunk-5-1.png b/man/figures/README-unnamed-chunk-5-1.png index 430fe91..2f7c412 100644 Binary files a/man/figures/README-unnamed-chunk-5-1.png and b/man/figures/README-unnamed-chunk-5-1.png differ diff --git a/man/figures/README-unnamed-chunk-6-1.png b/man/figures/README-unnamed-chunk-6-1.png index ce72116..eb5587b 100644 Binary files a/man/figures/README-unnamed-chunk-6-1.png and b/man/figures/README-unnamed-chunk-6-1.png differ diff --git a/man/figures/README-unnamed-chunk-7-1.png b/man/figures/README-unnamed-chunk-7-1.png index 00dc164..f7ddcf4 100644 Binary files a/man/figures/README-unnamed-chunk-7-1.png and b/man/figures/README-unnamed-chunk-7-1.png differ diff --git a/man/import.Dataset.Rd b/man/import.Dataset.Rd index f780a81..d9c6c3b 100644 --- a/man/import.Dataset.Rd +++ b/man/import.Dataset.Rd @@ -1,32 +1,17 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/import_LL.R +\docType{data} \name{import.Dataset} \alias{import.Dataset} -\alias{import.ActLumus} -\alias{import.LYS} +\alias{import} \title{Import a light logger dataset or related data} +\format{ +An object of class \code{list} of length 3. +} \usage{ import.Dataset(device, ...) -import.ActLumus( - filename, - path = NULL, - n_max = Inf, - tz = "UTC", - ID.colname = Id, - auto.id = ".*", - manual.id = NULL -) - -import.LYS( - filename, - path = NULL, - n_max = Inf, - tz = "UTC", - ID.colname = Id, - auto.id = ".*", - manual.id = NULL -) +import } \arguments{ \item{device}{From what device do you want to import? For every supported @@ -36,34 +21,10 @@ by the \code{device.ext} spec to access the sample file): \itemize{ \item \code{"ActLumus"} (ActLumus.txt) \item \code{"LYS"} (LYS.csv) +\item \code{"Actiwatch_Spectrum"} (Actiwatch.csv) \emph{Note: as the \code{locale} argument use \code{readr::locale(encoding="latin1")} . This is due to the fact that the German Actiwatch software from which this sample file was taken, uses a different encoding than UTF-8.} }} \item{...}{Parameters that get handed down to the specific import functions} - -\item{filename}{Filename(s) for the Dataset. Can also contain the filepath, -but \code{path} must then be \code{NULL}. Expects a \code{character}. If the vector is -longer than \code{1}, multiple files will be read in into one Tibble.} - -\item{path}{Optional path for the dataset(s). \code{NULL} is the default. Expects -a \code{character}.} - -\item{n_max}{maximum number of lines to read. Default is \code{Inf}.} - -\item{tz}{Timezone of the data. \code{"UTC"} is the default. Expects a -\code{character}. You can look up the supported timezones with \code{\link[=OlsonNames]{OlsonNames()}}.} - -\item{ID.colname}{Lets you specify a column for the participant id. Expects a -symbol (Default is \code{Id}). This column will be used for grouping -(\code{\link[dplyr:group_by]{dplyr::group_by()}}).} - -\item{auto.id}{If the \code{Id.colname} column is added to the \code{dataset}, the \code{Id} -can be automatically extracted from the filename. The argument expects a -regular expression \link{regex} and will by default just give the whole filename -without file extension.} - -\item{manual.id}{If this argument is not \code{NULL}, and no \code{ID} column is part -of the \code{dataset}, this \code{character} scalar will be used. -\strong{Don´t use this argument if multiple files from different participants are used!}.} } \value{ Tibble/Dataframe with a POSIXct column for the datetime @@ -73,11 +34,39 @@ Imports a dataset and does the necessary transformations to get the right column formats. Unless specified otherwise, the function will set the timezone of the data to \code{UTC}. It will also enforce an \code{id} to separate different datasets and will order/arrange the dataset within each \code{id}. + +There are specific and a general import function. The general import function +is described below, whereas the specific import functions take the form of +\code{import$device()}. The general import function is a thin wrapper around the +specific import functions. The specific import functions take the following +arguments: +\itemize{ +\item \code{filename}: Filename(s) for the Dataset. Can also contain the filepath, +but \code{path} must then be \code{NULL}. Expects a \code{character}. If the vector is +longer than \code{1}, multiple files will be read in into one Tibble. +\item \code{path}: Optional path for the dataset(s). \code{NULL} is the default. Expects +a \code{character}. +\item \code{n_max}: maximum number of lines to read. Default is \code{Inf}. +\item \code{tz}: Timezone of the data. \code{"UTC"} is the default. Expects a +\code{character}. You can look up the supported timezones with \code{\link[=OlsonNames]{OlsonNames()}}. +\item \code{ID.colname}: Lets you specify a column for the participant id. Expects a +symbol (Default is \code{Id}). This column will be used for grouping +(\code{\link[dplyr:group_by]{dplyr::group_by()}}). +\item \code{auto.id}: If the \code{Id.colname} column is added to the \code{dataset}, the \code{Id} +can be automatically extracted from the filename. The argument expects a +regular expression \link{regex} and will by default just give the whole filename +without file extension. +\item \code{manual.id}: If this argument is not \code{NULL}, and no \code{ID} column is part +of the \code{dataset}, this \code{character} scalar will be used. \strong{Don´t use this +argument if multiple files from different participants are used!} +\item \code{locale}: The locale controls defaults that vary from place to place. +\item \code{...}: supply additional arguments to the \link{readr} import functions, like \code{na}. Might also be used to supply arguments to the specific import functions, like \code{column_names} for \code{Actiwatch_Spectrum} devices. Those devices will alway throw a helpful error message if you forget to supply the necessary arguments. +} } \details{ -If the \code{Id} column is already part of the \code{dataset} it will just use this -column. If the column is not present it will add this column and fill it with -the filename of the importfile (see param \code{auto.id}). +If the \code{Id} column is already part of the \code{dataset} it will just use +this column. If the column is not present it will add this column and fill +it with the filename of the importfile (see param \code{auto.id}). } \section{Examples}{ @@ -91,7 +80,7 @@ just work out of the box. To get an overview, you can simply call the is maintained. \if{html}{\out{
}}\if{html}{\out{ }}\if{html}{\out{}}Id\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}Datetime\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}TEMPERATURE\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}LIGHT\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}MEDI\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{
---|---|---|---|---|
}}\if{html}{\out{ }}\if{html}{\out{}}sample_data_ActLumus\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}2023-07-14 13:04:18\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}29.88\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}21,847.64\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}20,660.74\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{
}}\if{html}{\out{ }}\if{html}{\out{}}sample_data_ActLumus\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}2023-07-14 13:05:18\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}29.88\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}22,033.77\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}20,834.91\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{
}}\if{html}{\out{ }}\if{html}{\out{}}sample_data_ActLumus\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}2023-07-14 13:06:18\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}29.81\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}21,769.50\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}20,600.82\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{
}}\if{html}{\out{ }}\if{html}{\out{}}sample_data_ActLumus\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}2023-07-14 13:07:18\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}29.69\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}21,177.20\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}20,061.68\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{
}}\if{html}{\out{ }}\if{html}{\out{}}sample_data_ActLumus\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}2023-07-14 13:08:18\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}29.44\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}20,738.98\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}19,662.14\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{
}}\if{html}{\out{ }}\if{html}{\out{}}sample_data_ActLumus\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}2023-07-14 13:09:18\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}29.31\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}20,255.17\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}19,203.94\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{
}}\if{html}{\out{ }}\if{html}{\out{}}Datetime\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}TEMPERATURE\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}LIGHT\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}MEDI\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}Id\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{
---|---|---|---|---|
}}\if{html}{\out{ }}\if{html}{\out{}}2023-07-14 13:04:18\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}29.88\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}21,847.64\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}20,660.74\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}sample_data_ActLumus\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{
}}\if{html}{\out{ }}\if{html}{\out{}}2023-07-14 13:05:18\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}29.88\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}22,033.77\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}20,834.91\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}sample_data_ActLumus\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{
}}\if{html}{\out{ }}\if{html}{\out{}}2023-07-14 13:06:18\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}29.81\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}21,769.50\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}20,600.82\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}sample_data_ActLumus\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{
}}\if{html}{\out{ }}\if{html}{\out{}}2023-07-14 13:07:18\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}29.69\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}21,177.20\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}20,061.68\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}sample_data_ActLumus\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{
}}\if{html}{\out{ }}\if{html}{\out{}}2023-07-14 13:08:18\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}29.44\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}20,738.98\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}19,662.14\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}sample_data_ActLumus\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{
}}\if{html}{\out{ }}\if{html}{\out{}}2023-07-14 13:09:18\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}29.31\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}20,255.17\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}19,203.94\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{}}sample_data_ActLumus\if{html}{\out{}}\if{html}{\out{ }}\if{html}{\out{ | }}\if{html}{\out{