This is an automated email from the git hooks/post-receive script. bob.dybian-guest pushed a commit to branch master in repository r-cran-fitbitscraper.
commit fc5389312796b3d6be79114f784c5bc3e0d46cb6 Author: Dylan Aïssi <[email protected]> Date: Sun Jun 12 05:14:25 2016 +0200 Imported Upstream version 0.1.7 --- DESCRIPTION | 8 +- MD5 | 11 ++- NEWS.md | 3 + README.md | 4 +- build/vignette.rds | Bin 0 -> 214 bytes inst/doc/fitbitScraper-examples.R | 74 +++++++++++++++ inst/doc/fitbitScraper-examples.Rmd | 109 ++++++++++++++++++++++ inst/doc/fitbitScraper-examples.html | 173 +++++++++++++++++++++++++++++++++++ vignettes/fitbitScraper-examples.Rmd | 109 ++++++++++++++++++++++ 9 files changed, 483 insertions(+), 8 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 25a8dea..dbc5491 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: fitbitScraper Title: Scrapes Data from Fitbit -Version: 0.1.6 +Version: 0.1.7 Author: Cory Nissen <[email protected]> [aut, cre] Maintainer: Cory Nissen <[email protected]> Description: Scrapes data from Fitbit <http://www.fitbit.com>. This does not use the official @@ -12,7 +12,9 @@ LazyData: true Imports: httr, stringr, jsonlite, methods, utils URL: https://github.com/corynissen/fitbitScraper RoxygenNote: 5.0.1 +Suggests: knitr, rmarkdown, ggplot2, ggthemes +VignetteBuilder: knitr NeedsCompilation: no -Packaged: 2016-04-11 15:13:52 UTC; 60018847 +Packaged: 2016-05-19 12:20:00 UTC; 60018847 Repository: CRAN -Date/Publication: 2016-04-11 18:38:35 +Date/Publication: 2016-05-19 20:31:18 diff --git a/MD5 b/MD5 index d27694e..ed44c3b 100644 --- a/MD5 +++ b/MD5 @@ -1,7 +1,7 @@ -0f2bb69c7fa616218574664c6aea3e36 *DESCRIPTION +1316fb002b8d2000506141b342b5435d *DESCRIPTION d499114c8fb7674b84d73553dd6e8d9a *LICENSE af05ec54f552800fae2fa87191cbef9c *NAMESPACE -88390e2e5dd3e55a0c71f936eb4f60bc *NEWS.md +6c6b1fe6226af70ba953aec1b66d5b32 *NEWS.md ca12202aff2a6dd5b672b54b269170fe *R/get_activity_data.R 6f22f81c632183d6bb0d26638f2741c5 *R/get_daily_data.R bbdfa193a0b307c8f634c89681ad87d1 *R/get_intraday_data.R @@ -9,7 +9,11 @@ c1b92b4d6f2af001a7c7227c927360f4 *R/get_premium_export.R a363b6cd2faa8a8ccfdb2052dfb42540 *R/get_sleep_data.R e541d7ca220d36967d1e210f94f6ce68 *R/get_weight_data.R 102dcc2840fa122eea731fa2f5b4b6c8 *R/login.R -9f7ac5485822d04895cd5ad0a64abf34 *README.md +a5dfa3c770b3e2fa88f19a8788a2bfeb *README.md +2b652519e0db5c2000f87c1fb9c79f13 *build/vignette.rds +0834d2d5146972b7fcf319fadfbb7c37 *inst/doc/fitbitScraper-examples.R +c7eceade09e11fbd5338f2da0b26a6d6 *inst/doc/fitbitScraper-examples.Rmd +da9afc6a287ba001a93f404c0255615c *inst/doc/fitbitScraper-examples.html b4bd6aacbc1f19392f02d757e13ac0ee *man/get_activity_data.Rd 5780a406e827724de4d3cc2b96913fd1 *man/get_daily_data.Rd b9312f0b0bace2795a3229bc19efeac3 *man/get_intraday_data.Rd @@ -17,3 +21,4 @@ b9312f0b0bace2795a3229bc19efeac3 *man/get_intraday_data.Rd cf2f8c7c4abd423007bdf5db9b0abd15 *man/get_sleep_data.Rd dc0c871efcadc80badd75074df7629af *man/get_weight_data.Rd 88fd5d742acc1558be0f54313b60c675 *man/login.Rd +c7eceade09e11fbd5338f2da0b26a6d6 *vignettes/fitbitScraper-examples.Rmd diff --git a/NEWS.md b/NEWS.md index 2a51958..3a8707d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,7 @@ +### fitbitScraper 0.1.7 +* added vignette + ### fitbitScraper 0.1.6 * switch from RJSONIO to jsonlite diff --git a/README.md b/README.md index 5ada605..602806b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -### fitbitScraper 0.1.6 +### fitbitScraper 0.1.7 This package scrapes data from fitbit.com It only works if you use email / password to login. Not sure about facebook or google login. @@ -12,7 +12,7 @@ library("fitbitScraper") cookie <- login(email="[email protected]", password="mypassword") # 15_min_data "what" options: "steps", "distance", "floors", "active-minutes", "calories-burned" -df <- get_activity_data(cookie, what="steps", date="2015-01-21") +df <- get_intraday_data(cookie, what="steps", date="2015-01-21") library("ggplot2") ggplot(df) + geom_bar(aes(x=time, y=data, fill=data), stat="identity") + xlab("") +ylab("steps") + diff --git a/build/vignette.rds b/build/vignette.rds new file mode 100644 index 0000000..ce0875b Binary files /dev/null and b/build/vignette.rds differ diff --git a/inst/doc/fitbitScraper-examples.R b/inst/doc/fitbitScraper-examples.R new file mode 100644 index 0000000..833a40b --- /dev/null +++ b/inst/doc/fitbitScraper-examples.R @@ -0,0 +1,74 @@ +## ------------------------------------------------------------------------ +library("fitbitScraper") +cookie <- login(email="[email protected]", password=Sys.getenv("FBPW")) + +## ---- fig.height=4, fig.width=5, message=FALSE, warning=FALSE, fig.align='center'---- +dates <- seq(as.Date("2016-04-03"), as.Date("2016-04-09"), by="day") +df_list <- lapply(dates, function(x) + get_intraday_data(cookie=cookie, what="steps", as.character(x))) +df <- do.call(rbind, df_list) + +library("ggplot2") +library("ggthemes") +ggplot(df) + + geom_bar(aes(x=time, y=steps), stat="identity") + + theme_tufte() + + scale_x_datetime(name="date", date_breaks="1 day", date_labels="%b-%d") + +## ---- fig.height=4, fig.width=5, message=FALSE, warning=FALSE, fig.align='center'---- +df <- get_daily_data(cookie=cookie, what="floors", start_date="2016-02-15", + end_date="2016-05-01") +df$weekday <- format(df$time, "%A") +avgs <- by(df$floors, df$weekday, mean) +avgs <- data.frame(day=names(avgs), floors=as.numeric(avgs)) +avgs$day <- factor(avgs$day, levels=avgs$day[c(4, 2, 6, 7, 5, 1, 3)]) + +ggplot(avgs) + + geom_bar(aes(x=day, y=floors), stat="identity") + + theme_tufte() + + xlab("") + + ylab("") + + ggtitle("Average Floors by Day 2016-02-15 to 2016-05-01") + + geom_text(aes(x=day,y=floors,label=round(floors, 1)), + vjust=1.1, colour="white") + + theme(axis.text.y=element_blank(), axis.ticks.y=element_blank()) + + theme(plot.title=element_text(vjust=.5)) + +## ---- fig.height=4, fig.width=5, message=FALSE, warning=FALSE, fig.align='center'---- +# don't do this... +# mywt <- get_weight_data(cookie, start_date="2015-01-01", end_date="2015-05-01") +start_date <- as.Date("2015-01-01") +end_date <- as.Date("2015-05-01") +wt_df_list <- list() # initialize a list to put the weight dataframes into +in_range <- TRUE # indicator variable to tell when to exit while loop +s_date <- start_date # date to start with during loop +while(in_range){ + e_date <- s_date + 14 + new_df <- get_weight_data(cookie, start_date=as.character(s_date), + end_date=as.character(e_date)) + wt_df_list[[as.character(s_date)]] <- new_df + s_date <- e_date + 1 + if(e_date > end_date) in_range <- FALSE +} +wt_df <- do.call(rbind, wt_df_list) +wt_df <- wt_df[!duplicated(wt_df$time), ] +wt_df <- wt_df[order(wt_df$time), ] +wt_df <- wt_df[as.Date(wt_df$time) >= start_date & + as.Date(wt_df$time) <= end_date, ] + +step_df <- get_daily_data(cookie=cookie, what="steps", start_date="2015-01-01", + end_date="2015-05-01") + +# get common date format to merge data sets... +wt_df$date <- as.character(as.Date(wt_df$time)) +step_df$date <- as.character(as.Date(step_df$time)) + +# merge by date +df <- merge(wt_df, step_df, by="date") + +# now plot +ggplot(df, aes(x=steps, y=weight)) + + geom_point() + + stat_smooth(se=FALSE) + + theme_tufte() + diff --git a/inst/doc/fitbitScraper-examples.Rmd b/inst/doc/fitbitScraper-examples.Rmd new file mode 100644 index 0000000..f2b3058 --- /dev/null +++ b/inst/doc/fitbitScraper-examples.Rmd @@ -0,0 +1,109 @@ +--- +title: "fitbitScraper Examples" +author: "Cory Nissen" +date: "5/5/2016" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{fitbitScraper Examples} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +## Installation +Install fitbitScraper as you would a normal library. It exists on [CRAN](https://cran.r-project.org/package=fitbitScraper), so a simple `install.packages("fitbitScraper")` should work. + +A development version exists on [Github](https://github.com/corynissen/fitbitScraper), and can be installed via [devtools](https://cran.r-project.org/package=devtools). `devtools::install_github("corynissen/fitbitScraper")` + +## Usage + +I've stored my password in an environment variable called "FBPW". I'll use this to login to fitbit and generate a cookie that will be used for the subsequent requests. You can type it directly in the password field, but it is generally a best practice to use an environment variable instead. Fitbit allows login via Google and Facebook. This library only works with an email / password based login. + +```{r} +library("fitbitScraper") +cookie <- login(email="[email protected]", password=Sys.getenv("FBPW")) +``` + +Now you can run any of the other functions to get your data. Let's start with getting steps on a 15 minute interval for a given week... + +```{r, fig.height=4, fig.width=5, message=FALSE, warning=FALSE, fig.align='center'} +dates <- seq(as.Date("2016-04-03"), as.Date("2016-04-09"), by="day") +df_list <- lapply(dates, function(x) + get_intraday_data(cookie=cookie, what="steps", as.character(x))) +df <- do.call(rbind, df_list) + +library("ggplot2") +library("ggthemes") +ggplot(df) + + geom_bar(aes(x=time, y=steps), stat="identity") + + theme_tufte() + + scale_x_datetime(name="date", date_breaks="1 day", date_labels="%b-%d") +``` + +You can get a daily summary of your data also. Here, I download data for the number of flights of stairs I climbed for the last two months. Then, compute the average number of flights of stairs by day, and graph it. Not surprisingly, I climb more stairs on the weekends when I'm home than I do at work during the week. Note that it is possible to get this data using `get_intraday_data()` for each day, but this is much more efficient using just one call to the fibit API for the entire date [...] + +```{r, fig.height=4, fig.width=5, message=FALSE, warning=FALSE, fig.align='center'} +df <- get_daily_data(cookie=cookie, what="floors", start_date="2016-02-15", + end_date="2016-05-01") +df$weekday <- format(df$time, "%A") +avgs <- by(df$floors, df$weekday, mean) +avgs <- data.frame(day=names(avgs), floors=as.numeric(avgs)) +avgs$day <- factor(avgs$day, levels=avgs$day[c(4, 2, 6, 7, 5, 1, 3)]) + +ggplot(avgs) + + geom_bar(aes(x=day, y=floors), stat="identity") + + theme_tufte() + + xlab("") + + ylab("") + + ggtitle("Average Floors by Day 2016-02-15 to 2016-05-01") + + geom_text(aes(x=day,y=floors,label=round(floors, 1)), + vjust=1.1, colour="white") + + theme(axis.text.y=element_blank(), axis.ticks.y=element_blank()) + + theme(plot.title=element_text(vjust=.5)) +``` + +Another thing to look at, especially if you have the [Aria scale](https://www.fitbit.com/aria), is your weight. You can record your weight manually in the fitbit app, which is how I do it, or the Aria scale will sync it automatically. Any how, let's graph my steps vs. weight for a time period and see if there seems to be a correlation. Data is returned for use in a graph on the fitbit page, so if you include a date range larger than two weeks or so, it returns data for a subset of the da [...] + +```{r, fig.height=4, fig.width=5, message=FALSE, warning=FALSE, fig.align='center'} +# don't do this... +# mywt <- get_weight_data(cookie, start_date="2015-01-01", end_date="2015-05-01") +start_date <- as.Date("2015-01-01") +end_date <- as.Date("2015-05-01") +wt_df_list <- list() # initialize a list to put the weight dataframes into +in_range <- TRUE # indicator variable to tell when to exit while loop +s_date <- start_date # date to start with during loop +while(in_range){ + e_date <- s_date + 14 + new_df <- get_weight_data(cookie, start_date=as.character(s_date), + end_date=as.character(e_date)) + wt_df_list[[as.character(s_date)]] <- new_df + s_date <- e_date + 1 + if(e_date > end_date) in_range <- FALSE +} +wt_df <- do.call(rbind, wt_df_list) +wt_df <- wt_df[!duplicated(wt_df$time), ] +wt_df <- wt_df[order(wt_df$time), ] +wt_df <- wt_df[as.Date(wt_df$time) >= start_date & + as.Date(wt_df$time) <= end_date, ] + +step_df <- get_daily_data(cookie=cookie, what="steps", start_date="2015-01-01", + end_date="2015-05-01") + +# get common date format to merge data sets... +wt_df$date <- as.character(as.Date(wt_df$time)) +step_df$date <- as.character(as.Date(step_df$time)) + +# merge by date +df <- merge(wt_df, step_df, by="date") + +# now plot +ggplot(df, aes(x=steps, y=weight)) + + geom_point() + + stat_smooth(se=FALSE) + + theme_tufte() +``` + +That last example illustrates one of the limitations of retrieving the data the way this library does. Instead of using the "official" fitbit API, this library uses the API intended for their website developer to use to build the visualizations on the web dashboard. So, there's no public documentation. This results in situations like the last one where the weight data returned by that API call is intended to be used in a chart, so they don't need more than 20 points, so that's all that i [...] + + + + diff --git a/inst/doc/fitbitScraper-examples.html b/inst/doc/fitbitScraper-examples.html new file mode 100644 index 0000000..abd7198 --- /dev/null +++ b/inst/doc/fitbitScraper-examples.html @@ -0,0 +1,173 @@ +<!DOCTYPE html> + +<html xmlns="http://www.w3.org/1999/xhtml"> + +<head> + +<meta charset="utf-8"> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> +<meta name="generator" content="pandoc" /> +<meta name="viewport" content="width=device-width, initial-scale=1"> + +<meta name="author" content="Cory Nissen" /> + + +<title>fitbitScraper Examples</title> + + + +<style type="text/css">code{white-space: pre;}</style> +<style type="text/css"> +div.sourceCode { overflow-x: auto; } +table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode { + margin: 0; padding: 0; vertical-align: baseline; border: none; } +table.sourceCode { width: 100%; line-height: 100%; } +td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; } +td.sourceCode { padding-left: 5px; } +code > span.kw { color: #007020; font-weight: bold; } /* Keyword */ +code > span.dt { color: #902000; } /* DataType */ +code > span.dv { color: #40a070; } /* DecVal */ +code > span.bn { color: #40a070; } /* BaseN */ +code > span.fl { color: #40a070; } /* Float */ +code > span.ch { color: #4070a0; } /* Char */ +code > span.st { color: #4070a0; } /* String */ +code > span.co { color: #60a0b0; font-style: italic; } /* Comment */ +code > span.ot { color: #007020; } /* Other */ +code > span.al { color: #ff0000; font-weight: bold; } /* Alert */ +code > span.fu { color: #06287e; } /* Function */ +code > span.er { color: #ff0000; font-weight: bold; } /* Error */ +code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */ +code > span.cn { color: #880000; } /* Constant */ +code > span.sc { color: #4070a0; } /* SpecialChar */ +code > span.vs { color: #4070a0; } /* VerbatimString */ +code > span.ss { color: #bb6688; } /* SpecialString */ +code > span.im { } /* Import */ +code > span.va { color: #19177c; } /* Variable */ +code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */ +code > span.op { color: #666666; } /* Operator */ +code > span.bu { } /* BuiltIn */ +code > span.ex { } /* Extension */ +code > span.pp { color: #bc7a00; } /* Preprocessor */ +code > span.at { color: #7d9029; } /* Attribute */ +code > span.do { color: #ba2121; font-style: italic; } /* Documentation */ +code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */ +code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */ +code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */ +</style> + + +<link href="data:text/css;charset=utf-8,body%20%7B%0Abackground%2Dcolor%3A%20%23fff%3B%0Amargin%3A%201em%20auto%3B%0Amax%2Dwidth%3A%20700px%3B%0Aoverflow%3A%20visible%3B%0Apadding%2Dleft%3A%202em%3B%0Apadding%2Dright%3A%202em%3B%0Afont%2Dfamily%3A%20%22Open%20Sans%22%2C%20%22Helvetica%20Neue%22%2C%20Helvetica%2C%20Arial%2C%20sans%2Dserif%3B%0Afont%2Dsize%3A%2014px%3B%0Aline%2Dheight%3A%201%2E35%3B%0A%7D%0A%23header%20%7B%0Atext%2Dalign%3A%20center%3B%0A%7D%0A%23TOC%20%7B%0Aclear%3A%20bot [...] + +</head> + +<body> + + + +<div class="fluid-row" id="header"> + + +<h1 class="title">fitbitScraper Examples</h1> +<h4 class="author"><em>Cory Nissen</em></h4> +<h4 class="date"><em>5/5/2016</em></h4> + +</div> + + +<div id="installation" class="section level2"> +<h2>Installation</h2> +<p>Install fitbitScraper as you would a normal library. It exists on <a href="https://cran.r-project.org/package=fitbitScraper">CRAN</a>, so a simple <code>install.packages("fitbitScraper")</code> should work.</p> +<p>A development version exists on <a href="https://github.com/corynissen/fitbitScraper">Github</a>, and can be installed via <a href="https://cran.r-project.org/package=devtools">devtools</a>. <code>devtools::install_github("corynissen/fitbitScraper")</code></p> +</div> +<div id="usage" class="section level2"> +<h2>Usage</h2> +<p>I’ve stored my password in an environment variable called “FBPW”. I’ll use this to login to fitbit and generate a cookie that will be used for the subsequent requests. You can type it directly in the password field, but it is generally a best practice to use an environment variable instead. Fitbit allows login via Google and Facebook. This library only works with an email / password based login.</p> +<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="kw">library</span>(<span class="st">"fitbitScraper"</span>) +cookie <-<span class="st"> </span><span class="kw">login</span>(<span class="dt">email=</span><span class="st">"[email protected]"</span>, <span class="dt">password=</span><span class="kw">Sys.getenv</span>(<span class="st">"FBPW"</span>))</code></pre></div> +<p>Now you can run any of the other functions to get your data. Let’s start with getting steps on a 15 minute interval for a given week…</p> +<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r">dates <-<span class="st"> </span><span class="kw">seq</span>(<span class="kw">as.Date</span>(<span class="st">"2016-04-03"</span>), <span class="kw">as.Date</span>(<span class="st">"2016-04-09"</span>), <span class="dt">by=</span><span class="st">"day"</span>) +df_list <-<span class="st"> </span><span class="kw">lapply</span>(dates, function(x) + <span class="kw">get_intraday_data</span>(<span class="dt">cookie=</span>cookie, <span class="dt">what=</span><span class="st">"steps"</span>, <span class="kw">as.character</span>(x))) +df <-<span class="st"> </span><span class="kw">do.call</span>(rbind, df_list) + +<span class="kw">library</span>(<span class="st">"ggplot2"</span>) +<span class="kw">library</span>(<span class="st">"ggthemes"</span>) +<span class="kw">ggplot</span>(df) +<span class="st"> </span> +<span class="st"> </span><span class="kw">geom_bar</span>(<span class="kw">aes</span>(<span class="dt">x=</span>time, <span class="dt">y=</span>steps), <span class="dt">stat=</span><span class="st">"identity"</span>) +<span class="st"> </span> +<span class="st"> </span><span class="kw">theme_tufte</span>() +<span class="st"> </span> +<span class="st"> </span><span class="kw">scale_x_datetime</span>(<span class="dt">name=</span><span class="st">"date"</span>, <span class="dt">date_breaks=</span><span class="st">"1 day"</span>, <span class="dt">date_labels=</span><span class="st">"%b-%d"</span>)</code></pre></div> +<p><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAeAAAAGACAMAAABC/kH9AAAAolBMVEUAAAAAADoAAGYAOjoAOpAAZmYAZrY6AAA6ADo6AGY6OpA6ZrY6kNtZWVlmAABmADpmAGZmOpBmZgBmZrZmkNtmtttmtv+QOgCQOjqQOmaQZpCQkDqQkLaQkNuQtv+Q27aQ2/+2ZgC2Zma2kJC2tma2tv+2/9u2///bkDrbkGbbkJDb29vb2//b/7bb////tmb/tpD/trb/25D//7b//9v///+8OLqoAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAMiUlEQVR4nO3cC3ubRhbGcZL1Wtusxk2a1k7SbWplL1azqZRF4vt/tR2ELiDNAGdgQBz93+cJsWUd5mh+4mZjJxlRnWTsBkjcAKw8ACsPwMoDsPIArDwAKw/AygOw8gCsPAArD8DKA7DyAKw8ACsPw [...] +<p>You can get a daily summary of your data also. Here, I download data for the number of flights of stairs I climbed for the last two months. Then, compute the average number of flights of stairs by day, and graph it. Not surprisingly, I climb more stairs on the weekends when I’m home than I do at work during the week. Note that it is possible to get this data using <code>get_intraday_data()</code> for each day, but this is much more efficient using just one call to the fibit API for th [...] +<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r">df <-<span class="st"> </span><span class="kw">get_daily_data</span>(<span class="dt">cookie=</span>cookie, <span class="dt">what=</span><span class="st">"floors"</span>, <span class="dt">start_date=</span><span class="st">"2016-02-15"</span>, + <span class="dt">end_date=</span><span class="st">"2016-05-01"</span>) +df$weekday <-<span class="st"> </span><span class="kw">format</span>(df$time, <span class="st">"%A"</span>) +avgs <-<span class="st"> </span><span class="kw">by</span>(df$floors, df$weekday, mean) +avgs <-<span class="st"> </span><span class="kw">data.frame</span>(<span class="dt">day=</span><span class="kw">names</span>(avgs), <span class="dt">floors=</span><span class="kw">as.numeric</span>(avgs)) +avgs$day <-<span class="st"> </span><span class="kw">factor</span>(avgs$day, <span class="dt">levels=</span>avgs$day[<span class="kw">c</span>(<span class="dv">4</span>, <span class="dv">2</span>, <span class="dv">6</span>, <span class="dv">7</span>, <span class="dv">5</span>, <span class="dv">1</span>, <span class="dv">3</span>)]) + +<span class="kw">ggplot</span>(avgs) +<span class="st"> </span> +<span class="st"> </span><span class="kw">geom_bar</span>(<span class="kw">aes</span>(<span class="dt">x=</span>day, <span class="dt">y=</span>floors), <span class="dt">stat=</span><span class="st">"identity"</span>) +<span class="st"> </span> +<span class="st"> </span><span class="kw">theme_tufte</span>() +<span class="st"> </span> +<span class="st"> </span><span class="kw">xlab</span>(<span class="st">""</span>) +<span class="st"> </span> +<span class="st"> </span><span class="kw">ylab</span>(<span class="st">""</span>) +<span class="st"> </span> +<span class="st"> </span><span class="kw">ggtitle</span>(<span class="st">"Average Floors by Day 2016-02-15 to 2016-05-01"</span>) +<span class="st"> </span> +<span class="st"> </span><span class="kw">geom_text</span>(<span class="kw">aes</span>(<span class="dt">x=</span>day,<span class="dt">y=</span>floors,<span class="dt">label=</span><span class="kw">round</span>(floors, <span class="dv">1</span>)), + <span class="dt">vjust=</span><span class="fl">1.1</span>, <span class="dt">colour=</span><span class="st">"white"</span>) +<span class="st"> </span> +<span class="st"> </span><span class="kw">theme</span>(<span class="dt">axis.text.y=</span><span class="kw">element_blank</span>(), <span class="dt">axis.ticks.y=</span><span class="kw">element_blank</span>()) +<span class="st"> </span> +<span class="st"> </span><span class="kw">theme</span>(<span class="dt">plot.title=</span><span class="kw">element_text</span>(<span class="dt">vjust=</span>.<span class="dv">5</span>)) </code></pre></div> +<p><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAeAAAAGACAMAAABC/kH9AAABLFBMVEUAAAAAADoAAGYAOjoAOpAAZrY6AAA6ADo6AGY6OgA6Ojo6OmY6OpA6ZmY6ZpA6ZrY6kLY6kNtZWVlZWXhZWZRZeLFZlMtmAABmADpmAGZmOpBmZgBmZrZmkLZmkNtmtrZmtttmtv94WVl4seWQOgCQOjqQOmaQZgCQZmaQZpCQkDqQkJCQkLaQkNuQtpCQtv+Q27aQ29uQ2/+UWVmUeLGUy/+xeFmxlLGx5f+2ZgC2Zjq2Zma2kDq2kJC2tma2tra2tv+225C22/+2/7a2/9u2///LlFnL/+XL///bkDrbkGbbkJDbtmbbtrbb25Db27bb29vb/7bb///lsXjl5eXl/8vl/+Xl////tmb/tpD/trb/y5T/25D/5bH/5eX//7b//8v//9v//+X///9Uo [...] +<p>Another thing to look at, especially if you have the <a href="https://www.fitbit.com/aria">Aria scale</a>, is your weight. You can record your weight manually in the fitbit app, which is how I do it, or the Aria scale will sync it automatically. Any how, let’s graph my steps vs. weight for a time period and see if there seems to be a correlation. Data is returned for use in a graph on the fitbit page, so if you include a date range larger than two weeks or so, it returns data for a su [...] +<div class="sourceCode"><pre class="sourceCode r"><code class="sourceCode r"><span class="co"># don't do this...</span> +<span class="co"># mywt <- get_weight_data(cookie, start_date="2015-01-01", end_date="2015-05-01")</span> +start_date <-<span class="st"> </span><span class="kw">as.Date</span>(<span class="st">"2015-01-01"</span>) +end_date <-<span class="st"> </span><span class="kw">as.Date</span>(<span class="st">"2015-05-01"</span>) +wt_df_list <-<span class="st"> </span><span class="kw">list</span>() <span class="co"># initialize a list to put the weight dataframes into</span> +in_range <-<span class="st"> </span><span class="ot">TRUE</span> <span class="co"># indicator variable to tell when to exit while loop</span> +s_date <-<span class="st"> </span>start_date <span class="co"># date to start with during loop</span> +while(in_range){ + e_date <-<span class="st"> </span>s_date +<span class="st"> </span><span class="dv">14</span> + new_df <-<span class="st"> </span><span class="kw">get_weight_data</span>(cookie, <span class="dt">start_date=</span><span class="kw">as.character</span>(s_date), + <span class="dt">end_date=</span><span class="kw">as.character</span>(e_date)) + wt_df_list[[<span class="kw">as.character</span>(s_date)]] <-<span class="st"> </span>new_df + s_date <-<span class="st"> </span>e_date +<span class="st"> </span><span class="dv">1</span> + if(e_date ><span class="st"> </span>end_date) in_range <-<span class="st"> </span><span class="ot">FALSE</span> +} +wt_df <-<span class="st"> </span><span class="kw">do.call</span>(rbind, wt_df_list) +wt_df <-<span class="st"> </span>wt_df[!<span class="kw">duplicated</span>(wt_df$time), ] +wt_df <-<span class="st"> </span>wt_df[<span class="kw">order</span>(wt_df$time), ] +wt_df <-<span class="st"> </span>wt_df[<span class="kw">as.Date</span>(wt_df$time) >=<span class="st"> </span>start_date & +<span class="st"> </span><span class="kw">as.Date</span>(wt_df$time) <=<span class="st"> </span>end_date, ] + +step_df <-<span class="st"> </span><span class="kw">get_daily_data</span>(<span class="dt">cookie=</span>cookie, <span class="dt">what=</span><span class="st">"steps"</span>, <span class="dt">start_date=</span><span class="st">"2015-01-01"</span>, + <span class="dt">end_date=</span><span class="st">"2015-05-01"</span>) + +<span class="co"># get common date format to merge data sets...</span> +wt_df$date <-<span class="st"> </span><span class="kw">as.character</span>(<span class="kw">as.Date</span>(wt_df$time)) +step_df$date <-<span class="st"> </span><span class="kw">as.character</span>(<span class="kw">as.Date</span>(step_df$time)) + +<span class="co"># merge by date</span> +df <-<span class="st"> </span><span class="kw">merge</span>(wt_df, step_df, <span class="dt">by=</span><span class="st">"date"</span>) + +<span class="co"># now plot</span> +<span class="kw">ggplot</span>(df, <span class="kw">aes</span>(<span class="dt">x=</span>steps, <span class="dt">y=</span>weight)) +<span class="st"> </span> +<span class="st"> </span><span class="kw">geom_point</span>() +<span class="st"> </span> +<span class="st"> </span><span class="kw">stat_smooth</span>(<span class="dt">se=</span><span class="ot">FALSE</span>) +<span class="st"> </span> +<span class="st"> </span><span class="kw">theme_tufte</span>()</code></pre></div> +<p><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAeAAAAGACAMAAABC/kH9AAAAnFBMVEUAAAAAADoAAGYAOjoAOpAAZmYAZrYzZv86AAA6AGY6OpA6ZrY6kNtmAABmADpmAGZmOpBmZgBmZrZmkNtmtrZmtv+QOgCQOjqQOmaQZpCQkDqQkNuQtv+Q27aQ2/+2ZgC2Zma2kJC2tv+225C2/9u2///bkDrbkGbbkJDbtmbb2//b/7bb////tmb/tpD/trb/25D//7b//9v///822OzOAAAACXBIWXMAAA7DAAAOwwHHb6hkAAALrElEQVR4nO2dC3vaOBpGnUw2IS00M82QtNsW0tmFzu5Ca+P//9/WMjdjG+OL5MvLOU/jgoFPHxxk2TKSvRCk8bpOANyCYHEQLA6CxUGwOAgWB8HiIFgcBIuDYHEQLA6CxUGwOAgWB8HiIFgcBIuDYHGKBc/H0 [...] +<p>That last example illustrates one of the limitations of retrieving the data the way this library does. Instead of using the “official” fitbit API, this library uses the API intended for their website developer to use to build the visualizations on the web dashboard. So, there’s no public documentation. This results in situations like the last one where the weight data returned by that API call is intended to be used in a chart, so they don’t need more than 20 points, so that’s all tha [...] +</div> + + + +<!-- dynamically load mathjax for compatibility with self-contained --> +<script> + (function () { + var script = document.createElement("script"); + script.type = "text/javascript"; + script.src = "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"; + document.getElementsByTagName("head")[0].appendChild(script); + })(); +</script> + +</body> +</html> diff --git a/vignettes/fitbitScraper-examples.Rmd b/vignettes/fitbitScraper-examples.Rmd new file mode 100644 index 0000000..f2b3058 --- /dev/null +++ b/vignettes/fitbitScraper-examples.Rmd @@ -0,0 +1,109 @@ +--- +title: "fitbitScraper Examples" +author: "Cory Nissen" +date: "5/5/2016" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{fitbitScraper Examples} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +## Installation +Install fitbitScraper as you would a normal library. It exists on [CRAN](https://cran.r-project.org/package=fitbitScraper), so a simple `install.packages("fitbitScraper")` should work. + +A development version exists on [Github](https://github.com/corynissen/fitbitScraper), and can be installed via [devtools](https://cran.r-project.org/package=devtools). `devtools::install_github("corynissen/fitbitScraper")` + +## Usage + +I've stored my password in an environment variable called "FBPW". I'll use this to login to fitbit and generate a cookie that will be used for the subsequent requests. You can type it directly in the password field, but it is generally a best practice to use an environment variable instead. Fitbit allows login via Google and Facebook. This library only works with an email / password based login. + +```{r} +library("fitbitScraper") +cookie <- login(email="[email protected]", password=Sys.getenv("FBPW")) +``` + +Now you can run any of the other functions to get your data. Let's start with getting steps on a 15 minute interval for a given week... + +```{r, fig.height=4, fig.width=5, message=FALSE, warning=FALSE, fig.align='center'} +dates <- seq(as.Date("2016-04-03"), as.Date("2016-04-09"), by="day") +df_list <- lapply(dates, function(x) + get_intraday_data(cookie=cookie, what="steps", as.character(x))) +df <- do.call(rbind, df_list) + +library("ggplot2") +library("ggthemes") +ggplot(df) + + geom_bar(aes(x=time, y=steps), stat="identity") + + theme_tufte() + + scale_x_datetime(name="date", date_breaks="1 day", date_labels="%b-%d") +``` + +You can get a daily summary of your data also. Here, I download data for the number of flights of stairs I climbed for the last two months. Then, compute the average number of flights of stairs by day, and graph it. Not surprisingly, I climb more stairs on the weekends when I'm home than I do at work during the week. Note that it is possible to get this data using `get_intraday_data()` for each day, but this is much more efficient using just one call to the fibit API for the entire date [...] + +```{r, fig.height=4, fig.width=5, message=FALSE, warning=FALSE, fig.align='center'} +df <- get_daily_data(cookie=cookie, what="floors", start_date="2016-02-15", + end_date="2016-05-01") +df$weekday <- format(df$time, "%A") +avgs <- by(df$floors, df$weekday, mean) +avgs <- data.frame(day=names(avgs), floors=as.numeric(avgs)) +avgs$day <- factor(avgs$day, levels=avgs$day[c(4, 2, 6, 7, 5, 1, 3)]) + +ggplot(avgs) + + geom_bar(aes(x=day, y=floors), stat="identity") + + theme_tufte() + + xlab("") + + ylab("") + + ggtitle("Average Floors by Day 2016-02-15 to 2016-05-01") + + geom_text(aes(x=day,y=floors,label=round(floors, 1)), + vjust=1.1, colour="white") + + theme(axis.text.y=element_blank(), axis.ticks.y=element_blank()) + + theme(plot.title=element_text(vjust=.5)) +``` + +Another thing to look at, especially if you have the [Aria scale](https://www.fitbit.com/aria), is your weight. You can record your weight manually in the fitbit app, which is how I do it, or the Aria scale will sync it automatically. Any how, let's graph my steps vs. weight for a time period and see if there seems to be a correlation. Data is returned for use in a graph on the fitbit page, so if you include a date range larger than two weeks or so, it returns data for a subset of the da [...] + +```{r, fig.height=4, fig.width=5, message=FALSE, warning=FALSE, fig.align='center'} +# don't do this... +# mywt <- get_weight_data(cookie, start_date="2015-01-01", end_date="2015-05-01") +start_date <- as.Date("2015-01-01") +end_date <- as.Date("2015-05-01") +wt_df_list <- list() # initialize a list to put the weight dataframes into +in_range <- TRUE # indicator variable to tell when to exit while loop +s_date <- start_date # date to start with during loop +while(in_range){ + e_date <- s_date + 14 + new_df <- get_weight_data(cookie, start_date=as.character(s_date), + end_date=as.character(e_date)) + wt_df_list[[as.character(s_date)]] <- new_df + s_date <- e_date + 1 + if(e_date > end_date) in_range <- FALSE +} +wt_df <- do.call(rbind, wt_df_list) +wt_df <- wt_df[!duplicated(wt_df$time), ] +wt_df <- wt_df[order(wt_df$time), ] +wt_df <- wt_df[as.Date(wt_df$time) >= start_date & + as.Date(wt_df$time) <= end_date, ] + +step_df <- get_daily_data(cookie=cookie, what="steps", start_date="2015-01-01", + end_date="2015-05-01") + +# get common date format to merge data sets... +wt_df$date <- as.character(as.Date(wt_df$time)) +step_df$date <- as.character(as.Date(step_df$time)) + +# merge by date +df <- merge(wt_df, step_df, by="date") + +# now plot +ggplot(df, aes(x=steps, y=weight)) + + geom_point() + + stat_smooth(se=FALSE) + + theme_tufte() +``` + +That last example illustrates one of the limitations of retrieving the data the way this library does. Instead of using the "official" fitbit API, this library uses the API intended for their website developer to use to build the visualizations on the web dashboard. So, there's no public documentation. This results in situations like the last one where the weight data returned by that API call is intended to be used in a chart, so they don't need more than 20 points, so that's all that i [...] + + + + -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/r-cran-fitbitscraper.git _______________________________________________ debian-med-commit mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/debian-med-commit
