In this series of posts, I’ll show how to use models available in our repository of methods for analyzing accelerometer data.
Our Purpose
Similar to my post on the Steenbock et al. (2019) algorithm, this post will highlight another method found in our repository. Montoye et al. (2019) published six models for predicting energy expenditure from count or raw acceleration metrics at the hip, wrist, or both. Similar to the Steenbock et al. (2019) model, the authors published example data with the metrics already calculated. Below I’ll illustrate how to calculate the necessary features and apply Montoye et al.’s (2019) hip-worn count-based model. A similar approach would apply to the other published models.
Calculating Features
As always, we first load necessary packages.
tryCatch(library(nnet),error=function(e){install.packages("nnet");library(nnet)})
tryCatch(library(data.table),error=function(e){install.packages("data.table ");library(data.table)})
We then load the model and see which features it needs as inputs (and the variable names it expects).
load("hip_count.RData")
nnet_hip_count$coefnames
[1] "MeanCounts_RH_y" "MeanCounts_RH_x" "MeanCounts_RH_z" "VarCounts_RH_y" "VarCounts_RH_x"
[6] "VarCounts_RH_z"
These are all easy enough to calculate! We first read in our 1-sec counts data as a csv.
data<-AGread::read_AG_counts(“File1.csv”,skip=11)
Then we use lubridate’s floor_data function which rounds the timestamp down to the specified epoch, which in this case is 15 seconds.
data$Timestamp15 <- lubridate::floor_date(data$Timestamp, "15 sec")
We can then get the mean and variance in counts in each axis, which we will rename to match what Montoye et al.’s (2019) neural network is expecting as input. Since we are using data.table to calculate these features, we have to first set our data as a data.table using setDT.
setDT(data)
data15sec<-data[,c(mean=lapply(.SD,mean),var=lapply(.SD,var)),by=c("Timestamp15"),.SDcols=c("Axis1","Axis2","Axis3")]
names(data15sec)<-c("Timestamp15","MeanCounts_RH_y","MeanCounts_RH_x","MeanCounts_RH_z","VarCounts_RH_y","VarCounts_RH_x","VarCounts_RH_z")
Predicting METs
Then we apply the neural network to predict energy expenditure (as METs) for each epoch. If desired, you can also classify these METs as sedentary, light, moderate, or vigorous intensity. Note that the cut function classifies the variable METs but the cut-points you provide are treated as inclusive. In this example, 3 METs would be classified as moderate, but if you made the cut-point “3,” then 3 METs would be classified as light.
data15sec$mets<-predict(nnet_hip_count,data15sec)
data15sec$mets<-(cut(as.vector(data15sec$mets),breaks=c(-Inf,1.5,2.9999, 5.9999, Inf),labels=c("sed","light","mod",”vig”)))
Putting it All Together
We may want to run this whole process as a function.
montoye<-function(x) {
data<-AGread::read_AG_counts(x,skip=11)
data<-data[,1:4]
data$id<-x
data$Timestamp15 <- lubridate::floor_date(data$Timestamp, "15 sec")
data.table::setDT(data)
data15sec<-data[,c(mean=lapply(.SD,mean),var=lapply(.SD,var)),by=c("id","Timestamp15"),.SDcols=c("Axis1","Axis2","Axis3")]
names(data15sec)<-c("id","Timestamp15","MeanCounts_RH_y","MeanCounts_RH_x","MeanCounts_RH_z","VarCounts_RH_y","VarCounts_RH_x","VarCounts_RH_z")
data15sec$mets<-predict(nnet_hip_count,data15sec)
data15sec$actclass<-(cut(as.vector(data15sec$mets),breaks=c(-Inf,1.5,2.9999, 5.9999, Inf),labels=c("sed","light","mod","vig")))
return(data15sec)
}
filenames<-list.files(pattern="*.csv")
data<-try(lapply(filenames,montoye) %>% bind_rows())
What we end up with is all of our metrics, predicted METs, and METs classified as sedentary, light, moderate, or vigorous activity for each 15-s epoch.
id Timestamp15 MeanCounts_RH_y MeanCounts_RH_x MeanCounts_RH_z VarCounts_RH_y
1: File1.csv 2019-05-20 08:00:00 0 0 0 0
2: File1.csv 2019-05-20 08:00:15 0 0 0 0
3: File1.csv 2019-05-20 08:00:30 0 0 0 0
4: File1.csv 2019-05-20 08:00:45 0 0 0 0
5: File1.csv 2019-05-20 08:01:00 0 0 0 0
6: File1.csv 2019-05-20 08:01:15 0 0 0 0
VarCounts_RH_x VarCounts_RH_z mets actclass
1: 0 0 2.554064 light
2: 0 0 2.554064 light
3: 0 0 2.554064 light
4: 0 0 2.554064 light
5: 0 0 2.554064 light
6: 0 0 2.554064 light
That’s it!