Skip to content

Commit

Permalink
Merge pull request #19 from bhelsel/development
Browse files Browse the repository at this point in the history
agcounts 0.6.4
  • Loading branch information
bhelsel authored Jul 21, 2023
2 parents af6d5e8 + d2a18e2 commit 446ee4c
Show file tree
Hide file tree
Showing 32 changed files with 569 additions and 104 deletions.
4 changes: 2 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: agcounts
Type: Package
Title: R Package for Extracting Actigraphy Counts from Accelerometer Data
Version: 0.6.2
Version: 0.6.4
Authors@R: c(
person(c("Brian", "C."), "Helsel", email = "[email protected]",
role = c("aut", "cre")),
Expand All @@ -12,7 +12,7 @@ Description: This R Package reads the X, Y, and Z axes in a GT3X accelerometer f
The link to the article (https://www.researchsquare.com/article/rs-1370418/v1) and Python implementation of this code (https://github.com/actigraph/agcounts).
Depends:
R (>= 3.5.0)
License: MIT + file LICENSE
License: file LICENSE
Encoding: UTF-8
LazyData: true
RoxygenNote: 7.2.3
Expand Down
5 changes: 3 additions & 2 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
YEAR: 2022
COPYRIGHT HOLDER: agcounts authors
Copyright © 2022 University of Kansas. All rights reserved.

Creative Commons Attribution NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)
422 changes: 401 additions & 21 deletions LICENSE.md

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# agcounts 0.6.4
* Updated the agcounts license with KU Copyright and Creative Commons (CC BY-NC-SA 4.0).
* Changed the parsers to reflect the Python and R package names.
* Created more flexibility for adding a Shiny app theme.
* Extending the `.last_complete_epoch` function after discovering a file that did not find a complete epoch.


# agcounts 0.6.3
* Improved test coverage including tests for the Shiny Server
* Removed the Shiny App from the inst folder to only make it a callable app using `agShinyDeployApp`
Expand Down
4 changes: 4 additions & 0 deletions R/agcounts.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Copyright © 2022 University of Kansas. All rights reserved.
#
# Creative Commons Attribution NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)

#' @title agcounts: R Package for Extracting Actigraphy Counts from Accelerometer Data.
#'
#' @description This R Package reads the X, Y, and Z axes in a GT3X accelerometer file
Expand Down
13 changes: 8 additions & 5 deletions R/agcountsShinyApp.R
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
# Copyright © 2022 University of Kansas. All rights reserved.
#
# Creative Commons Attribution NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)

#' @title agShinyDeployApp
#' @description This function deploys the agcounts Shiny app.
#' @return No data or values are returned.
#' @details This function deploys the agcounts Shiny app for data visualization
#' and exploration. It also provides an opportunity to compare ActiGraph counts
#' generated from the agcounts package with those from ActiGraph's .agd files.
#' @param shinyTheme Change the theme of the shiny app using the \code{\link[bslib]{bs_theme}} function, Default: 'spacelab'
#' @param ... arguments passed to \code{\link[shiny]{shinyApp}}
#' @param ... arguments passed to \code{\link[bslib]{bs_theme}}
#' @seealso
#' \code{\link[shiny]{fluidPage}}, \code{\link[shiny]{titlePanel}}, \code{\link[shiny]{reexports}}, \code{\link[shiny]{shinyApp}}
#' \code{\link[bslib]{bs_theme}}
Expand All @@ -21,9 +24,9 @@
#' @importFrom dplyr mutate group_by summarise select mutate_at
#' @importFrom stats sd

agShinyDeployApp <-function(shinyTheme = "spacelab", ...){
agShinyDeployApp <-function(...){
ui <- shiny::fluidPage(
theme = bslib::bs_theme(bootswatch = shinyTheme),
theme = bslib::bs_theme(...),
shiny::titlePanel("agcounts: An R Package to Calculate ActiGraph Counts"),
shiny::h3("Import and Visualize Raw Acceleration Data"),
rawDataModuleUI("rawDataModule"),
Expand All @@ -39,7 +42,7 @@ agShinyDeployApp <-function(shinyTheme = "spacelab", ...){
compareCountsModuleServer("compareCountsModule", filteredData)
}

shiny::shinyApp(ui, server, ...)
shiny::shinyApp(ui, server)
}

#' @title .agPlotTheme
Expand Down
36 changes: 20 additions & 16 deletions R/agread.R
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
# Copyright © 2022 University of Kansas. All rights reserved.
#
# Creative Commons Attribution NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)

#' @title Read in raw acceleration data
#' @description This generic function reads in calibrated raw acceleration data
#' from the python module pygt3x or the R GGIR package or uncalibrated data
#' from the read.gt3x package.
#' @description This function reads in raw acceleration data
#' with the pygt3x Python package, the read.gt3x R package with GGIR autocalibration, or the read.gt3x R package.
#' @param path Path name to the GT3X file or the dataset with columns time, X, Y, and Z axis
#' @param verbose Print the read method, Default: FALSE.
#' @param parser The parser to use when reading in the data. Parser values include pygt3x, ggir, and uncalibrated readers
#' @param parser The parser to use when reading in the data. Parser values include pygt3x, GGIR, and read.gt3x options.
#' @param tz the desired timezone, Default: \code{UTC}
#' @param ... Additional arguments to pass into the agread function
#' @return Returns the calibrated or uncalibrated raw acceleration data
#' @details This function reads in calibrated raw acceleration data from GGIR or pygt3x.
#' @return Returns the raw acceleration data
#' @details This function reads in raw acceleration data
#' with the pygt3x Python package, the read.gt3x R package with GGIR autocalibration, or the read.gt3x R package.
#' @examples
#' \dontrun{
#' agread(system.file("extdata/example.gt3x", package = "agcounts"), parser = "pygt3x")
Expand All @@ -22,22 +26,22 @@
#' @importFrom GGIR g.calibrate
#' @importFrom read.gt3x read.gt3x

agread <- function(path, parser = c("pygt3x", "ggir", "uncalibrated"), tz = "UTC", verbose = FALSE, ...){
agread <- function(path, parser = c("pygt3x", "GGIR", "read.gt3x"), tz = "UTC", verbose = FALSE, ...){
parser = match.arg(parser)

if(parser == "pygt3x" & !reticulate::py_module_available("pygt3x")) {
message('Python module "pygt3x" is not found. Switching parser to GGIR.')
parser <- "ggir"
parser <- "GGIR"
}
switch(parser,
"pygt3x" = .pygt3xReader(path = path, verbose = verbose, ...),
"ggir" = .ggirReader(path = path, verbose = verbose, ...),
"uncalibrated" = .uncalibratedReader(path = path, verbose = verbose, ...),
"GGIR" = .ggirReader(path = path, verbose = verbose, ...),
"read.gt3x" = .gt3xReader(path = path, verbose = verbose, ...),
stop("No method exists yet for ", sQuote(parser), call. = FALSE)
)
}

.pygt3xReader <- function(path, parser = c("pygt3x", "ggir", "gt3x"), tz = "UTC", verbose = FALSE, ...){
.pygt3xReader <- function(path, tz = "UTC", verbose = FALSE, ...){
reader <- NULL
if(!reticulate::py_module_available("pygt3x")) stop('Python module "pygt3x" not found.')
if(verbose) print("Reading and calibrating data with pygt3x.")
Expand All @@ -62,17 +66,17 @@ agread <- function(path, parser = c("pygt3x", "ggir", "uncalibrated"), tz = "UTC
raw
}

.ggirReader <- function(path, parser = c("pygt3x", "ggir", "gt3x"), tz = "UTC", verbose = FALSE, ...){
.ggirReader <- function(path, tz = "UTC", verbose = FALSE, ...){
if(verbose) print("Reading data with read.gt3x and calibrating with GGIR.")
C <- GGIR::g.calibrate(datafile = path, use.temp = FALSE, printsummary = FALSE)
raw <- read.gt3x::read.gt3x(path, asDataFrame = TRUE, imputeZeroes = TRUE)
raw[, 2:4] <- scale(raw[, 2:4], center = -C$offset, scale = 1/C$scale)
if(C$nhoursused==0) message("\n There is not enough data to perform the GGIR calibration method. Returning uncalibrated data.")
if(C$nhoursused==0) message("\n There is not enough data to perform the GGIR autocalibration method. Returning data as read by read.gt3x.")
raw
}

.uncalibratedReader <- function(path, parser = c("pygt3x", "ggir", "gt3x"), tz = "UTC", verbose = FALSE, ...){
if(verbose) print("Reading uncalibrated with read.gt3x.")
.gt3xReader <- function(path, tz = "UTC", verbose = FALSE, ...){
if(verbose) print("Reading data with read.gt3x.")
raw <- read.gt3x::read.gt3x(path, asDataFrame = TRUE, imputeZeroes = TRUE)
raw
}
Expand Down Expand Up @@ -114,7 +118,7 @@ agcalibrate <- function(raw, verbose = FALSE, tz = "UTC", ...){
raw[which(is.na(raw[, 3])), 3] <- 0
raw[which(is.na(raw[, 4])), 4] <- 0
raw[, c("X", "Y", "Z")] <- scale(raw[, c("X", "Y", "Z")], center = -C$offset, scale = 1/C$scale)
if(C$nhoursused==0) message("\n There is not enough data to perform the GGIR calibration method. Returning uncalibrated data.")
if(C$nhoursused==0) message("\n There is not enough data to perform the GGIR calibration method. Returning data as read by read.gt3x.")
raw
}

Expand Down
4 changes: 4 additions & 0 deletions R/calculate_counts.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Copyright © 2022 University of Kansas. All rights reserved.
#
# Creative Commons Attribution NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)

#' @title calculate_counts
#' @description Calculate ActiGraph activity counts from raw acceleration data
#' by passing in a data frame with a time stamp, X, Y, and Z axis. This function
Expand Down
4 changes: 4 additions & 0 deletions R/compareCountsModule.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Copyright © 2022 University of Kansas. All rights reserved.
#
# Creative Commons Attribution NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)

#' @title compareCountsModuleUI
#' @description UI for compareCountsModule
#' @noRd
Expand Down
4 changes: 4 additions & 0 deletions R/countsModule.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Copyright © 2022 University of Kansas. All rights reserved.
#
# Creative Commons Attribution NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)

#' @title countsModuleUI
#' @description UI for countsModuleUI
#' @noRd
Expand Down
8 changes: 6 additions & 2 deletions R/get_counts.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Copyright © 2022 University of Kansas. All rights reserved.
#
# Creative Commons Attribution NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)

#' @title get_counts
#' @description Main function to extract counts from the Actigraph GT3X Files.
#' @param path Full path name to the GT3X File
Expand All @@ -7,7 +11,7 @@
#' @param return.data Return the data frame to the R Global Environment, Default: TRUE
#' @param verbose Print the progress of the Actigraph raw data conversion to counts, Default: FALSE.
#' @param tz the desired timezone, Default: \code{UTC}
#' @param parser The parser to use when reading in the data. Parser values include pygt3x, ggir, and gt3x (uncalibrated reader).
#' @param parser The parser to use when reading in the data. Parser values include pygt3x, GGIR, and read.gt3x options.
#' @param ... arguments passed to \code{\link[data.table]{fwrite}}
#' @return Returns a CSV file if write.file is TRUE or a data frame if return.data is TRUE
#' @details Main function to extract counts from the Actigraph GT3X Files.
Expand All @@ -26,7 +30,7 @@
get_counts <- function(
path, epoch, lfe_select = FALSE, write.file = FALSE,
return.data = TRUE, verbose = FALSE, tz = "UTC",
parser = c("pygt3x", "ggir", "uncalibrated"), ...
parser = c("pygt3x", "GGIR", "read.gt3x"), ...
){

if(verbose){
Expand Down
4 changes: 4 additions & 0 deletions R/get_sleep.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Copyright © 2022 University of Kansas. All rights reserved.
#
# Creative Commons Attribution NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)

#' @export
#' @keywords internal
.get_sleep <- function(raw, ...) {
Expand Down
6 changes: 5 additions & 1 deletion R/get_timestamps.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Copyright © 2022 University of Kansas. All rights reserved.
#
# Creative Commons Attribution NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)

.get_timestamps <- function(raw, epoch, frequency, tz) {

if("start_time" %in% names(attributes(raw))){
Expand Down Expand Up @@ -25,7 +29,7 @@

samples_per_epoch <- frequency * epoch

utils::tail(raw$time, samples_per_epoch * 3) %>%
utils::tail(raw$time, samples_per_epoch * 10) %>%
lubridate::floor_date(paste(epoch, "sec")) %>%
as.character(.) %>%
rle(.) %>%
Expand Down
4 changes: 4 additions & 0 deletions R/global_vars.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Copyright © 2022 University of Kansas. All rights reserved.
#
# Creative Commons Attribution NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)

if(getRversion() >= "2.15.1") utils::globalVariables(c(
".", "Axis1", "Axis2", "Axis3", "Vector.Magnitude", "time"
))
Expand Down
4 changes: 4 additions & 0 deletions R/helpers.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Copyright © 2022 University of Kansas. All rights reserved.
#
# Creative Commons Attribution NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)

#' @title .check_idle_sleep
#' @description Check for missing raw data in the Actigraph file
#' @param raw A data frame of the raw Actigraph data that will be checked for missing data.
Expand Down
21 changes: 13 additions & 8 deletions R/rawDataModule.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Copyright © 2022 University of Kansas. All rights reserved.
#
# Creative Commons Attribution NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)

#' @title rawDataModuleUI
#' @description UI for rawDataModuleUI
#' @noRd
Expand All @@ -8,7 +12,7 @@ rawDataModuleUI <- function(id) {
shiny::sidebarLayout(
shiny::sidebarPanel(
shiny::fileInput(ns("gt3xFile"), "Choose GT3X File", multiple = FALSE, accept = c(".gt3x")),
shiny::radioButtons(ns("parser"), "Select your parser", choices = c("pygt3x", "ggir", "uncalibrated", "agcalibrate"), inline = TRUE, selected = 0),
shiny::radioButtons(ns("parser"), "Select your parser", choices = c("pygt3x", "GGIR", "read.gt3x", "agcalibrate"), inline = TRUE, selected = 0),
shiny::uiOutput(ns("dateAccessed")),
shiny::uiOutput(ns("timeSlot")),
shiny::selectInput(ns("axisRaw"), "Raw Axis", choices = c("X", "Y", "Z", "Vector.Magnitude"), selected = "Y"),
Expand Down Expand Up @@ -119,16 +123,16 @@ rawDataModuleServer <- function(id) {

# Data Processing ----

# Read in the uncalibrated data with the read.gt3x function
uncalibratedData <- shiny::reactive({
# Read in the data with the read.gt3x function
rawData <- shiny::reactive({
shiny::req(input$gt3xFile)
read.gt3x::read.gt3x(input$gt3xFile$datapath, asDataFrame = TRUE)
})

# Read in the calibrated data with the read.gt3x function
calibratedData <- shiny::reactive({
shiny::req(input$gt3xFile, input$parser)
if(input$parser == "agcalibrate") data <- agcalibrate(uncalibratedData())
if(input$parser == "agcalibrate") data <- agcalibrate(rawData())
if(input$parser != "agcalibrate") data <- agread(path = input$gt3xFile$datapath, parser = input$parser)
data$Vector.Magnitude <- sqrt(data$X^2 + data$Y^2 + data$Z^2)
return(data)
Expand Down Expand Up @@ -232,18 +236,19 @@ rawDataModuleServer <- function(id) {

output$sampleFrequency <- shiny::renderText({
shiny::req(input$gt3xFile)
sf <- .get_frequency(uncalibratedData())
sf <- .get_frequency(rawData())
paste("The sample frequency is", sf, "Hertz.")
})


output$calibrationMethod <- shiny::renderUI({
shiny::req(input$gt3xFile, input$parser)
msgParser <-
switch(input$parser,
"pygt3x" = paste("<b><br>You chose the", input$parser, "parser.</b>", "<br>Description: Data is calibrated using the ActiGraph's pygt3x python module."),
"ggir" = paste("<b><br>You chose the", input$parser, "parser.</b>", "<br>Description: Data is calibrated using the GGIR g.calibrate function."),
"uncalibrated" = paste("<b><br>You chose the", input$parser, "parser.</b>", "<br>Description: Data is uncalibrated and read with the R read.gt3x package."),
"agcalibrate" = paste("<b><br>You chose the", input$parser, "parser.</b>", "<br>Description: Data is calibrated using a C++ version of the GGIR g.calibrate function."))
"GGIR" = paste("<b><br>You chose the", input$parser, "parser.</b>", "<br>Description: Data is read with the read.gt3x R package and calibrated with GGIR autocalibration."),
"read.gt3x" = paste("<b><br>You chose the", input$parser, "parser.</b>", "<br>Description: Data is read with the read.gt3x R package."),
"agcalibrate" = paste("<b><br>You chose the", input$parser, "parser.</b>", "<br>Description: Data is read with the read.gt3x R package and calibrated using a C++ version of the GGIR autocalibration."))
shiny::HTML(msgParser)
})

Expand Down
4 changes: 4 additions & 0 deletions R/zzz.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Copyright © 2022 University of Kansas. All rights reserved.
#
# Creative Commons Attribution NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)

pygt3x <- NULL

.onLoad <- function(libname, pkgname) {
Expand Down
6 changes: 2 additions & 4 deletions man/agShinyDeployApp.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 7 additions & 7 deletions man/agread.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions man/get_counts.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 446ee4c

Please sign in to comment.