-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathregressionfitbitdata.r
195 lines (165 loc) · 8.41 KB
/
regressionfitbitdata.r
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# Inspiration from http://pdwhomeautomation.blogspot.com/2016/01/using-r-to-analyse-fitbit-api-data.html
# also http://hydroecology.net/getting-detailed-fitbit-data-with-r/
# The Fitbit API Documentation is found at https://dev.fitbit.com/reference
# Mostly using https://dev.fitbit.com/reference/web-api
# Code is for example only; Oauth2.0 info is missing, and this code will not run as-is
# These libraries are mostly for communications with API (httr) and parsing JSON output (jsonlite)
library(jsonlite)
library(devtools)
devtools::install_github("r-lib/httr#485")
library(httr)
library(plyr)
# For setting up API authorication with OAuth2.0 protocol
# Reset Client SecretRevoke Client Access Tokens
# OAuth 2.0 Client ID
# The below info was generated by Fitbit when I registered my app
#clientID <- generated by Fitbit
# Client Secret
#secretID <- generated by Fitbit site
# Callback URL
callback <- "http://localhost:1410/"
# OAuth 2.0: Authorization URI
auth_url <- "https://www.fitbit.com/oauth2/authorize"
# OAuth 2.0: Access/Refresh Token Request URI
token_url <- "https://api.fitbit.com/oauth2/token"
#setting up httr info based on the info I used to register my app with Fitbit
fbr <- oauth_app(name,clientID,secretID)
fitbit <- oauth_endpoint(authorize = auth_url, access = token_url)
# some help from https://github.com/r-lib/httr/pull/485 regarding 401 access token error
token <- oauth2.0_token(fitbit,fbr, scope=c("activity", "heartrate", "sleep"), use_basic_auth = TRUE)
conf <- config(token = token)
# All data is culled from the range of July 15th through October 15th
# Date range chosen to give almost daily stats
# "Calories burned inclusive of BMR according to movement captured by a Fitbit tracker."
cals <- GET("https://api.fitbit.com/1/user/-/activities/tracker/calories/date/2017-07-15/2017-10-15.json", config=conf)
calories <- fromJSON(content(cals, as="text"))
calorieFrame <- data.frame(calories)
names(calorieFrame) <- c("Date", "Calories")
# this data is imported as type character
# must convert to integers
calorieFrame$Calories <- as.integer((calorieFrame$Calories))
#a range of steps data from July 15th until Oct 15th
stepRange <- GET("https://api.fitbit.com/1/user/-/activities/tracker/steps/date/2017-07-15/2017-10-15.json", config = conf)
steps <- fromJSON(content(stepRange, as="text"))
stepFrame <- data.frame(steps)
names(stepFrame) <- c("Date", "Steps")
# checking in console with typeof() shows this imports the num. of steps are type char
# must convert to integer
stepFrame$Steps <- as.integer((stepFrame$Steps))
#a range of lightly active minutes data from July 15th until Oct 15th
lightRange <- GET("https://api.fitbit.com/1/user/-/activities/tracker/minutesLightlyActive/date/2017-07-15/2017-10-15.json", config = conf)
lights <- fromJSON(content(lightRange, as="text"))
lightFrame <- data.frame(lights)
names(lightFrame) <- c("Date", "Lightly active minutes")
#a range of fairly active minutes data from July 15th until Oct 15th
fairRange <- GET("https://api.fitbit.com/1/user/-/activities/tracker/minutesFairlyActive/date/2017-07-15/2017-10-15.json", config = conf)
fairs <- fromJSON(content(fairRange, as="text"))
fairFrame <- data.frame(fairs)
names(fairFrame) <- c("Date", "Fairly active minutes")
#a range of very active minutes data from July 15th until Oct 15th
veryRange <- GET("https://api.fitbit.com/1/user/-/activities/tracker/minutesVeryActive/date/2017-07-15/2017-10-15.json", config = conf)
verys <- fromJSON(content(veryRange, as="text"))
veryFrame <- data.frame(verys)
names(veryFrame) <- c("Date", "Very active minutes")
# making one table with these three categories
activeFrame <-data.frame(cbind(lightFrame, fairFrame$`Fairly active minutes`, veryFrame$`Very active minutes`))
names(activeFrame) <- c("Date", "Lightly active minutes", "Fairly active minutes", "Very active minutes")
remove(lightFrame, fairFrame, veryFrame)
# converting to integers
activeFrame$`Lightly active minutes` <- as.integer((activeFrame$`Lightly active minutes`))
activeFrame$`Fairly active minutes` <- as.integer(activeFrame$`Fairly active minutes`)
activeFrame$`Very active minutes` <- as.integer(activeFrame$`Very active minutes`)
# setting to three-level categorical
# only the two columns for fairly and very active will be included in the model
# 0,0 -> highest level is light, 1,0 -> highest level is fairly, 0,1 -> highest level is very
for(i in c(1:93)){
if(as.integer(activeFrame[i,4]) >1){
activeFrame[i,4]=1;
activeFrame[i,3]=0;
activeFrame[i,2]=0;
} else if (as.integer(activeFrame[i,3]) >1) {
activeFrame[i,4]=0
activeFrame[i,3]=1
activeFrame$`Lightly active minutes`[i]=0
} else{
activeFrame$`Very active minutes`[i]=0
activeFrame$`Fairly active minutes`[i]=0
activeFrame$`Lightly active minutes`[i]=1
}
}
#a range of average heart rate data from July 15th until Oct 15th
heartRange <- GET("https://api.fitbit.com/1/user/-/activities/heart/date/2017-07-15/2017-10-15.json", config = conf)
heart <- fromJSON(content(heartRange, as="text"))
hearts <- data.frame(heart)
heartFrame <- data.frame(hearts$activities.heart.dateTime, hearts$activities.heart.value$restingHeartRate)
names(heartFrame) <- c("Date", "Avg Rate")
#This code is the sleep data for July 15th through October 15th
snooze <- GET("https://api.fitbit.com/1.2/user/-/sleep/date/2017-07-15/2017-10-15.json", config=conf)
sleep <- fromJSON(content(snooze, as="text"))
sleepyFrame <- data.frame(sleep)
# Only interested in date and length of sleep
sleepFrame <- data.frame(sleepyFrame[[1]], sleepyFrame[[2]])
names(sleepFrame) <- c("Date", "Duration")
#make sure in chronological order
sleepFrame <- sleepFrame[order(sleepFrame$Date),]
remove(sleepyFrame)
sleepFrame$Date <- paste(sleepFrame$Date)
# also the length of sleep is returned in milliseconds - will change to hours
# convert by dividing first by 1000 to convert to seconds
# then by 3600 to convert to hours
sleepFrame[2] <- sleepFrame[2]/3600000
# Since I didn't wear my Fitbit every night, some nights' sleep is missing.
missingDates <- list("2017-08-18", "2017-08-22", "2017-09-23", "2017-09-24")
for (i in 1:4){
newFrame <-data.frame(missingDates[i],mean(sleepFrame$Duration))
names(newFrame) <-names(sleepFrame)
sleepFrame <- rbind(sleepFrame, newFrame)
}
# Some days like 8/28 are listed twice
# those three pairs of entries will each be summed to a daily total
doubleDates <- c("2017-08-28", "2017-09-15", "2017-10-09")
doubleFrame <- data.frame()
daysSleep <- c(0,0,0)
for (i in 1:3){
for (j in 1:length(sleepFrame[[1]])){
if (sleepFrame[j,1] == doubleDates[i]){
newsFrame <- data.frame(sleepFrame[j,1], sleepFrame[j,2])
doubleFrame <-rbind(doubleFrame, newsFrame)
}
}
for (j in 1:length(doubleFrame[[1]])){
if(doubleFrame[j,1]==doubleDates[i]){
daysSleep[i] <- sum(as.numeric(daysSleep[i]), doubleFrame[j,2])
}
}
}
# Now we build a data frame with the three dates affected and the sum of sleep
doubleDays <- data.frame(cbind(doubleDates, daysSleep))
names(doubleDays) <- names(sleepFrame)
# Now to substitute these into the main data frame for sleep data
cleanSleepFrame <- data.frame()
for (j in 1:length(sleepFrame[[1]])){
if (sleepFrame[j,1] != doubleDates[1] && sleepFrame[j,1] != doubleDates[2] && sleepFrame[j,1] != doubleDates[3]){
cleanSleepFrame <-rbind(cleanSleepFrame, sleepFrame[j,])
}
}
cleanSleepFrame <- rbind(cleanSleepFrame, as.data.frame(doubleDays))
# reordering chronologically
sleepFrame <- cleanSleepFrame[order(cleanSleepFrame$Date),]
sleepFrame$Duration <- as.numeric(sleepFrame$Duration)
# removing items created in cleaning process
remove(cleanSleepFrame, doubleDays, daysSleep, newsFrame, missingDates, doubleFrame, newFrame, snooze)
# weather data from https://www.njweather.org/data/daily/111
weather <- read.csv("/temperature.csv")
weather <- weather[order(weather$date),]
# days I was present on school campus, for class or activity
onCampus <- c(seq(0,0, length.out = 93))
onCampus[c(45, 53, 55, 57, 60, 62, 67, 69, 74, 76, 81, 83, 88, 90)] <- 1
# Constructing the myData frame!
myData <- data.frame()
myData <- cbind(calorieFrame[,], stepFrame$Steps, activeFrame[,3:4], heartFrame$`Avg Rate`, sleepFrame$Duration, weather$temperatureavg_daily, onCampus)
names(myData) <- c('date', 'calories', 'steps', 'fairlyActive', 'veryActive', 'heartRate', 'sleep', 'temp', 'onCampus')
# Now we have a lot of nice data to play with!
remove(calorieFrame, heartFrame, stepFrame, weather, activeFrame, hearts)
# export CSV of data
write.csv(myData, "myData.csv")