###Overview
Urška Sršen and Sando Mur founded Bellabeat, a high-tech company that manufactures health-focused smart products. Sršen used her background as an artist to develop beautifully designed technology that informs and inspires women around the world. Collecting data on activity, sleep, stress, and reproductive health has allowed Bellabeat to empower women with knowledge about their own health and habits. Since it was founded in 2013, Bellabeat has grown rapidly and quickly positioned itself as a tech-driven wellness company for women.
Analyze smart device usage data in order to gain insight into how consumers use non-Bellabeat smart devices
#2.1 High-level requirements
What are some trends in smart device usage?
How could these trends apply to Bellabeat customers?
How could these trends help influence Bellabeat marketing strategy?
Completing this case study within a week is a good goal.
#2.2 Deliverables
A clear summary of the business task
A description of all data sources used
Documentation of any cleaning or manipulation of data
A summary of your analysis
Supporting visualizations and key findings
Your top high-level content recommendations based on your analysis
#2.3 Affected parties
○ Urška Sršen: Bellabeat’s co-founder and Chief Creative Officer
○ Sando Mur: Mathematician and Bellabeat’s co-founder; key member of the Bellabeat executive team
○ Bellabeat marketing
#2.4 Case Study Roadmap
**1. Ask**
Review and analyze the data or how consumers use non-Bellabeat products, in order to found insight that allow Bellabeat achieve better users experience.
**2. Prepare**
Data: https://www.kaggle.com/datasets/arashnic/fitbit/data
○ Store: C:\Users\halex\OneDrive\Documents\My Learning\Google Data Analytics\Capstone\Case Study 2 - Copy Data
§ Fitabase Data 3.12.16-4.11.16 - II
§ Fitabase Data 4.12.16-5.12.16 - II
○ Long Data
○ Month Record: from March to May 2016
§ Updated 5 month ago (Today 08/8/2024)
○ Utility of 8.5 by Kaggle
○ CCO: Public Domain
○ Source: *https://zenodo.org/record/53894#.X9oeh3Uzaao*
Given the limitation of data (2 months long) and not having any demographic information we could encounter bias. The sample could not be representative of the population, also the users Id are not constant at each table. That is why are result give us an operational approach.
##3 Process & Analyze
a. Data - Process
1. Review tables and define which ones use for analysis
a. ID as Key Unique Identifier
b. Key Tables for Analysis:
i. dailyActivity-II
ii. heartrate_seconds-II
iii. minuteMETsNarrow-II
iv. weighLogInfo-II
v. hourlyCalories-II
vi. hourlySteps-II
vii. minuteSleep-II
c. Tableau UNION evidence
i. Data:
*C:\Users\halex\OneDrive\Documents\My Tableau PrepRepository\Datasources\CapstoneData-CaseStudy2 *
ii. Data: *CapstoneFlowData-CaseStudy2*
C:/Users/halex/AppData/Local/Temp/OneNote/16.0/Exported/{A629834E-2697-4926-99B3-220D3DCC4BCF}/NT/0/CapstoneFlowData-CaseStudy2.tflx
d. SQL UNION evidence
i. *https://console.cloud.google.com/bigquery?project=my-data-project-63779*
ii. SQL Dataset: FitBitFitnessTrackerData
iii. SQL Query
SELECT
*
FROM
`my-data-project-63779.FitBitFitnessTrackerData."Table Name from march to April 2016"` AS "table Name abreviation"_marchapr2016
UNION ALL
SELECT
*
FROM
`my-data-project-63779.FitBitFitnessTrackerData.Table Name from April to May 2016` AS "table Name abreviation"_aprmay2016
Save as CSV table Name _march-may2016
At C:\Users\halex\OneDrive\Documents\My Learning\Google Data Analytics\Capstone\Data
*-II → Means that is the union from March-April 2016 and April-May 2016*
##3.1 Process And Cleaning
**R Studio Analysis**
Set up my environment
Libraries
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ ggplot2 3.5.1 ✔ tibble 3.2.1
## ✔ lubridate 1.9.3 ✔ tidyr 1.3.1
## ✔ purrr 1.0.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(lubridate)
library(ggplot2)
library(readr)
library(janitor)
##
## Attaching package: 'janitor'
##
## The following objects are masked from 'package:stats':
##
## chisq.test, fisher.test
library(dplyr)
library(tidyr)
library(magrittr)
##
## Attaching package: 'magrittr'
##
## The following object is masked from 'package:purrr':
##
## set_names
##
## The following object is masked from 'package:tidyr':
##
## extract
library(ggpubr)
Read .csv files, as Data Summary
dailyActivity <- read_csv("C:\\Users\\halex\\OneDrive\\Documents\\My Tableau Prep Repository\\Datasources\\CapstoneData-CaseStudy2\\dailyActivity-II.csv")
## Rows: 1397 Columns: 15
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (1): ActivityDate
## dbl (14): Id, TotalSteps, TotalDistance, TrackerDistance, VeryActiveDistance...
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
heartrate <- read_csv("C:\\Users\\halex\\OneDrive\\Documents\\My Tableau Prep Repository\\Datasources\\CapstoneData-CaseStudy2\\heartrate_seconds-II.csv")
## Rows: 3638339 Columns: 3
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (1): Time
## dbl (2): Id, Value
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
minuteMETs <- read_csv("C:\\Users\\halex\\OneDrive\\Documents\\My Tableau Prep Repository\\Datasources\\CapstoneData-CaseStudy2\\minuteMETsNarrow-II.csv")
## Rows: 2770620 Columns: 4
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (2): Table Names, ActivityMinute
## dbl (2): Id, METs
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
hourlyCalories <- read_csv("C:\\Users\\halex\\OneDrive\\Documents\\My Tableau Prep Repository\\Datasources\\CapstoneData-CaseStudy2\\hourlyCalories-II.csv")
## Rows: 46183 Columns: 4
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (2): Table Names, ActivityHour
## dbl (2): Id, Calories
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
hourlySteps <- read_csv("C:\\Users\\halex\\OneDrive\\Documents\\My Tableau Prep Repository\\Datasources\\CapstoneData-CaseStudy2\\hourlySteps-II.csv")
## Rows: 48168 Columns: 4
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (2): Table Names, ActivityHour
## dbl (2): Id, StepTotal
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
minuteSleep <- read_csv("C:\\Users\\halex\\OneDrive\\Documents\\My Tableau Prep Repository\\Datasources\\CapstoneData-CaseStudy2\\minuteSleep-II.csv")
## Rows: 387080 Columns: 5
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (2): Table Names, date
## dbl (3): Id, value, logId
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
WeightLogInfo <- read_csv("C:\\Users\\halex\\OneDrive\\Documents\\My Tableau Prep Repository\\Datasources\\CapstoneData-CaseStudy2\\weighLogInfo-II.csv")
## Rows: 100 Columns: 9
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (2): Table Names, Date
## dbl (6): Id, WeightKg, WeightPounds, Fat, BMI, LogId
## lgl (1): IsManualReport
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
SleepDay <- read_csv("C:\\Users\\halex\\OneDrive\\Documents\\My Tableau Prep Repository\\Datasources\\CapstoneData-CaseStudy2\\SleepDay.csv")
## Rows: 413 Columns: 5
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (1): SleepDay
## dbl (4): Id, TotalSleepRecords, TotalMinutesAsleep, TotalTimeInBed
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
Look for duplicates
sum(duplicated(dailyActivity))
## [1] 0
sum(duplicated(hourlySteps))
## [1] 0
sum(duplicated(hourlyCalories))
## [1] 0
sum(duplicated(WeightLogInfo))
## [1] 0
sum(duplicated(minuteMETs))
## [1] 1926
sum(duplicated(minuteSleep))
## [1] 1789
sum(duplicated(heartrate))
## [1] 23424
sum(duplicated(SleepDay))
## [1] 3
The last four have duplicate values given the entries, no require elimination
clean SleepDay Duplicates
SleepDay <- SleepDay %>%
distinct() %>%
drop_na()
sum(duplicated(SleepDay))
## [1] 0
Clean Columns Names
clean_names(dailyActivity)
## # A tibble: 1,397 × 15
## id activity_date total_steps total_distance tracker_distance
## <dbl> <chr> <dbl> <dbl> <dbl>
## 1 1503960366 4/12/2016 13162 8.5 8.5
## 2 1503960366 4/13/2016 10735 6.97 6.97
## 3 1503960366 4/14/2016 10460 6.74 6.74
## 4 1503960366 4/15/2016 9762 6.28 6.28
## 5 1503960366 4/16/2016 12669 8.16 8.16
## 6 1503960366 4/17/2016 9705 6.48 6.48
## 7 1503960366 4/18/2016 13019 8.59 8.59
## 8 1503960366 4/19/2016 15506 9.88 9.88
## 9 1503960366 4/20/2016 10544 6.68 6.68
## 10 1503960366 4/21/2016 9819 6.34 6.34
## # ℹ 1,387 more rows
## # ℹ 10 more variables: very_active_distance <dbl>,
## # moderately_active_distance <dbl>, light_active_distance <dbl>,
## # sedentary_active_distance <dbl>, very_active_minutes <dbl>,
## # fairly_active_minutes <dbl>, lightly_active_minutes <dbl>,
## # sedentary_minutes <dbl>, calories <dbl>, logged_activities_distance <dbl>
clean_names(hourlySteps)
## # A tibble: 48,168 × 4
## table_names id activity_hour step_total
## <chr> <dbl> <chr> <dbl>
## 1 hourlySteps_merged.csv 1503960366 3/12/2016 12:00:00 AM 0
## 2 hourlySteps_merged.csv 1503960366 3/12/2016 1:00:00 AM 0
## 3 hourlySteps_merged.csv 1503960366 3/12/2016 2:00:00 AM 0
## 4 hourlySteps_merged.csv 1503960366 3/12/2016 3:00:00 AM 0
## 5 hourlySteps_merged.csv 1503960366 3/12/2016 4:00:00 AM 0
## 6 hourlySteps_merged.csv 1503960366 3/12/2016 5:00:00 AM 0
## 7 hourlySteps_merged.csv 1503960366 3/12/2016 6:00:00 AM 0
## 8 hourlySteps_merged.csv 1503960366 3/12/2016 7:00:00 AM 0
## 9 hourlySteps_merged.csv 1503960366 3/12/2016 8:00:00 AM 0
## 10 hourlySteps_merged.csv 1503960366 3/12/2016 9:00:00 AM 8
## # ℹ 48,158 more rows
clean_names(hourlyCalories)
## # A tibble: 46,183 × 4
## table_names id activity_hour calories
## <chr> <dbl> <chr> <dbl>
## 1 hourlyCalories_merged.csv 1503960366 4/12/2016 12:00:00 AM 81
## 2 hourlyCalories_merged.csv 1503960366 4/12/2016 1:00:00 AM 61
## 3 hourlyCalories_merged.csv 1503960366 4/12/2016 2:00:00 AM 59
## 4 hourlyCalories_merged.csv 1503960366 4/12/2016 3:00:00 AM 47
## 5 hourlyCalories_merged.csv 1503960366 4/12/2016 4:00:00 AM 48
## 6 hourlyCalories_merged.csv 1503960366 4/12/2016 5:00:00 AM 48
## 7 hourlyCalories_merged.csv 1503960366 4/12/2016 6:00:00 AM 48
## 8 hourlyCalories_merged.csv 1503960366 4/12/2016 7:00:00 AM 47
## 9 hourlyCalories_merged.csv 1503960366 4/12/2016 8:00:00 AM 68
## 10 hourlyCalories_merged.csv 1503960366 4/12/2016 9:00:00 AM 141
## # ℹ 46,173 more rows
clean_names(WeightLogInfo)
## # A tibble: 100 × 9
## table_names id date weight_kg weight_pounds fat bmi is_manual_report
## <chr> <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <lgl>
## 1 weightLogI… 1.50e9 4/5/… 53.3 118. 22 23.0 TRUE
## 2 weightLogI… 1.93e9 4/10… 130. 286. NA 46.2 FALSE
## 3 weightLogI… 2.35e9 4/3/… 63.4 140. 10 24.8 TRUE
## 4 weightLogI… 2.87e9 4/6/… 56.7 125. NA 21.5 TRUE
## 5 weightLogI… 2.87e9 4/7/… 57.2 126. NA 21.6 TRUE
## 6 weightLogI… 2.89e9 4/5/… 88.4 195. NA 25.0 TRUE
## 7 weightLogI… 4.45e9 3/30… 92.4 204. NA 35.0 TRUE
## 8 weightLogI… 4.56e9 4/8/… 69.4 153. NA 27.1 TRUE
## 9 weightLogI… 4.70e9 4/4/… 99.7 220. NA 26.1 TRUE
## 10 weightLogI… 6.96e9 3/30… 61.5 136. NA 24.0 TRUE
## # ℹ 90 more rows
## # ℹ 1 more variable: log_id <dbl>
clean_names(minuteMETs)
## # A tibble: 2,770,620 × 4
## table_names id activity_minute me_ts
## <chr> <dbl> <chr> <dbl>
## 1 minuteMETsNarrow_merged.csv 1927972279 3/25/2016 2:48:00 PM 10
## 2 minuteMETsNarrow_merged.csv 1927972279 3/25/2016 3:03:00 PM 10
## 3 minuteMETsNarrow_merged.csv 1927972279 3/25/2016 3:07:00 PM 10
## 4 minuteMETsNarrow_merged.csv 1927972279 3/25/2016 3:08:00 PM 10
## 5 minuteMETsNarrow_merged.csv 1927972279 3/25/2016 3:11:00 PM 10
## 6 minuteMETsNarrow_merged.csv 1927972279 3/25/2016 3:16:00 PM 10
## 7 minuteMETsNarrow_merged.csv 1927972279 3/25/2016 3:29:00 PM 10
## 8 minuteMETsNarrow_merged.csv 1927972279 3/25/2016 3:30:00 PM 10
## 9 minuteMETsNarrow_merged.csv 1927972279 3/25/2016 3:31:00 PM 10
## 10 minuteMETsNarrow_merged.csv 1927972279 3/25/2016 3:57:00 PM 10
## # ℹ 2,770,610 more rows
clean_names(minuteSleep)
## # A tibble: 387,080 × 5
## table_names id date value log_id
## <chr> <dbl> <chr> <dbl> <dbl>
## 1 minuteSleep_merged.csv 5577150313 5/3/2016 1:55:30 PM 1 11560009516
## 2 minuteSleep_merged.csv 5577150313 5/3/2016 1:56:30 PM 1 11560009516
## 3 minuteSleep_merged.csv 5577150313 5/3/2016 1:57:30 PM 1 11560009516
## 4 minuteSleep_merged.csv 5577150313 5/3/2016 1:58:30 PM 1 11560009516
## 5 minuteSleep_merged.csv 5577150313 5/3/2016 1:59:30 PM 1 11560009516
## 6 minuteSleep_merged.csv 5577150313 5/3/2016 2:00:30 PM 1 11560009516
## 7 minuteSleep_merged.csv 5577150313 5/3/2016 2:01:30 PM 1 11560009516
## 8 minuteSleep_merged.csv 5577150313 5/3/2016 2:02:30 PM 1 11560009516
## 9 minuteSleep_merged.csv 5577150313 5/3/2016 2:03:30 PM 1 11560009516
## 10 minuteSleep_merged.csv 5577150313 5/3/2016 2:04:30 PM 1 11560009516
## # ℹ 387,070 more rows
clean_names(heartrate)
## # A tibble: 3,638,339 × 3
## id time value
## <dbl> <chr> <dbl>
## 1 2347167796 3/29/2016 10:49:30 PM 65
## 2 2347167796 3/29/2016 10:49:45 PM 65
## 3 2347167796 3/29/2016 10:49:50 PM 63
## 4 2347167796 3/29/2016 10:50:05 PM 63
## 5 2347167796 3/29/2016 10:50:20 PM 63
## 6 2347167796 3/29/2016 10:50:30 PM 62
## 7 2347167796 3/29/2016 10:50:40 PM 61
## 8 2347167796 3/29/2016 10:50:50 PM 62
## 9 2347167796 3/29/2016 10:51:05 PM 62
## 10 2347167796 3/29/2016 10:51:20 PM 61
## # ℹ 3,638,329 more rows
clean_names(SleepDay)
## # A tibble: 410 × 5
## id sleep_day total_sleep_records total_minutes_asleep total_time_in_bed
## <dbl> <chr> <dbl> <dbl> <dbl>
## 1 1.50e9 4/12/201… 1 327 346
## 2 1.50e9 4/13/201… 2 384 407
## 3 1.50e9 4/15/201… 1 412 442
## 4 1.50e9 4/16/201… 2 340 367
## 5 1.50e9 4/17/201… 1 700 712
## 6 1.50e9 4/19/201… 1 304 320
## 7 1.50e9 4/20/201… 1 360 377
## 8 1.50e9 4/21/201… 1 325 364
## 9 1.50e9 4/23/201… 1 361 384
## 10 1.50e9 4/24/201… 1 430 449
## # ℹ 400 more rows
Review date format at all tables Id must be a chr And Date Time have the dttm format
head(dailyActivity)
## # A tibble: 6 × 15
## Id ActivityDate TotalSteps TotalDistance TrackerDistance
## <dbl> <chr> <dbl> <dbl> <dbl>
## 1 1503960366 4/12/2016 13162 8.5 8.5
## 2 1503960366 4/13/2016 10735 6.97 6.97
## 3 1503960366 4/14/2016 10460 6.74 6.74
## 4 1503960366 4/15/2016 9762 6.28 6.28
## 5 1503960366 4/16/2016 12669 8.16 8.16
## 6 1503960366 4/17/2016 9705 6.48 6.48
## # ℹ 10 more variables: VeryActiveDistance <dbl>,
## # ModeratelyActiveDistance <dbl>, LightActiveDistance <dbl>,
## # SedentaryActiveDistance <dbl>, VeryActiveMinutes <dbl>,
## # FairlyActiveMinutes <dbl>, LightlyActiveMinutes <dbl>,
## # SedentaryMinutes <dbl>, Calories <dbl>, LoggedActivitiesDistance <dbl>
head(hourlySteps)
## # A tibble: 6 × 4
## `Table Names` Id ActivityHour StepTotal
## <chr> <dbl> <chr> <dbl>
## 1 hourlySteps_merged.csv 1503960366 3/12/2016 12:00:00 AM 0
## 2 hourlySteps_merged.csv 1503960366 3/12/2016 1:00:00 AM 0
## 3 hourlySteps_merged.csv 1503960366 3/12/2016 2:00:00 AM 0
## 4 hourlySteps_merged.csv 1503960366 3/12/2016 3:00:00 AM 0
## 5 hourlySteps_merged.csv 1503960366 3/12/2016 4:00:00 AM 0
## 6 hourlySteps_merged.csv 1503960366 3/12/2016 5:00:00 AM 0
head(hourlyCalories)
## # A tibble: 6 × 4
## `Table Names` Id ActivityHour Calories
## <chr> <dbl> <chr> <dbl>
## 1 hourlyCalories_merged.csv 1503960366 4/12/2016 12:00:00 AM 81
## 2 hourlyCalories_merged.csv 1503960366 4/12/2016 1:00:00 AM 61
## 3 hourlyCalories_merged.csv 1503960366 4/12/2016 2:00:00 AM 59
## 4 hourlyCalories_merged.csv 1503960366 4/12/2016 3:00:00 AM 47
## 5 hourlyCalories_merged.csv 1503960366 4/12/2016 4:00:00 AM 48
## 6 hourlyCalories_merged.csv 1503960366 4/12/2016 5:00:00 AM 48
head(WeightLogInfo)
## # A tibble: 6 × 9
## `Table Names` Id Date WeightKg WeightPounds Fat BMI IsManualReport
## <chr> <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <lgl>
## 1 weightLogInfo_m… 1.50e9 4/5/… 53.3 118. 22 23.0 TRUE
## 2 weightLogInfo_m… 1.93e9 4/10… 130. 286. NA 46.2 FALSE
## 3 weightLogInfo_m… 2.35e9 4/3/… 63.4 140. 10 24.8 TRUE
## 4 weightLogInfo_m… 2.87e9 4/6/… 56.7 125. NA 21.5 TRUE
## 5 weightLogInfo_m… 2.87e9 4/7/… 57.2 126. NA 21.6 TRUE
## 6 weightLogInfo_m… 2.89e9 4/5/… 88.4 195. NA 25.0 TRUE
## # ℹ 1 more variable: LogId <dbl>
head(minuteMETs)
## # A tibble: 6 × 4
## `Table Names` Id ActivityMinute METs
## <chr> <dbl> <chr> <dbl>
## 1 minuteMETsNarrow_merged.csv 1927972279 3/25/2016 2:48:00 PM 10
## 2 minuteMETsNarrow_merged.csv 1927972279 3/25/2016 3:03:00 PM 10
## 3 minuteMETsNarrow_merged.csv 1927972279 3/25/2016 3:07:00 PM 10
## 4 minuteMETsNarrow_merged.csv 1927972279 3/25/2016 3:08:00 PM 10
## 5 minuteMETsNarrow_merged.csv 1927972279 3/25/2016 3:11:00 PM 10
## 6 minuteMETsNarrow_merged.csv 1927972279 3/25/2016 3:16:00 PM 10
head(minuteSleep)
## # A tibble: 6 × 5
## `Table Names` Id date value logId
## <chr> <dbl> <chr> <dbl> <dbl>
## 1 minuteSleep_merged.csv 5577150313 5/3/2016 1:55:30 PM 1 11560009516
## 2 minuteSleep_merged.csv 5577150313 5/3/2016 1:56:30 PM 1 11560009516
## 3 minuteSleep_merged.csv 5577150313 5/3/2016 1:57:30 PM 1 11560009516
## 4 minuteSleep_merged.csv 5577150313 5/3/2016 1:58:30 PM 1 11560009516
## 5 minuteSleep_merged.csv 5577150313 5/3/2016 1:59:30 PM 1 11560009516
## 6 minuteSleep_merged.csv 5577150313 5/3/2016 2:00:30 PM 1 11560009516
head(heartrate)
## # A tibble: 6 × 3
## Id Time Value
## <dbl> <chr> <dbl>
## 1 2347167796 3/29/2016 10:49:30 PM 65
## 2 2347167796 3/29/2016 10:49:45 PM 65
## 3 2347167796 3/29/2016 10:49:50 PM 63
## 4 2347167796 3/29/2016 10:50:05 PM 63
## 5 2347167796 3/29/2016 10:50:20 PM 63
## 6 2347167796 3/29/2016 10:50:30 PM 62
head(SleepDay)
## # A tibble: 6 × 5
## Id SleepDay TotalSleepRecords TotalMinutesAsleep TotalTimeInBed
## <dbl> <chr> <dbl> <dbl> <dbl>
## 1 1503960366 4/12/2016 12:0… 1 327 346
## 2 1503960366 4/13/2016 12:0… 2 384 407
## 3 1503960366 4/15/2016 12:0… 1 412 442
## 4 1503960366 4/16/2016 12:0… 2 340 367
## 5 1503960366 4/17/2016 12:0… 1 700 712
## 6 1503960366 4/19/2016 12:0… 1 304 320
Notes: all dates ar in format mm/dd/year, no change required
Convert numeric vector to character vector: the “Id” field must be a character not a number
dailyActivity$Id <- as.character(dailyActivity$Id)
hourlySteps$Id <- as.character(hourlySteps$Id)
hourlyCalories$Id <- as.character(hourlyCalories$Id)
WeightLogInfo$Id <- as.character(WeightLogInfo$Id)
minuteMETs$Id <- as.character(minuteMETs$Id)
minuteSleep$Id <- as.character(minuteSleep$Id)
heartrate$Id <- as.character(heartrate$Id)
SleepDay$Id <- as.character(SleepDay$Id)
Change Data Type
dailyActivity <- dailyActivity%>%
rename(date = ActivityDate) %>%
mutate(date = as.POSIXct(date, format = "%m/%d/%Y"))
hourlySteps<- hourlySteps %>%
rename(date_time = ActivityHour) %>%
mutate(date_time = as.POSIXct(date_time,format ="%m/%d/%Y %I:%M:%S %p" , tz=Sys.timezone()))
head(hourlySteps)
## # A tibble: 6 × 4
## `Table Names` Id date_time StepTotal
## <chr> <chr> <dttm> <dbl>
## 1 hourlySteps_merged.csv 1503960366 2016-03-12 00:00:00 0
## 2 hourlySteps_merged.csv 1503960366 2016-03-12 01:00:00 0
## 3 hourlySteps_merged.csv 1503960366 2016-03-12 02:00:00 0
## 4 hourlySteps_merged.csv 1503960366 2016-03-12 03:00:00 0
## 5 hourlySteps_merged.csv 1503960366 2016-03-12 04:00:00 0
## 6 hourlySteps_merged.csv 1503960366 2016-03-12 05:00:00 0
hourlyCalories <- hourlyCalories %>%
rename(DateTime = ActivityHour) %>%
mutate(DateTime = as.POSIXct(DateTime,format="%m/%d/%Y %H:%M:%S",tz=Sys.timezone()))
head(hourlyCalories)
## # A tibble: 6 × 4
## `Table Names` Id DateTime Calories
## <chr> <chr> <dttm> <dbl>
## 1 hourlyCalories_merged.csv 1503960366 2016-04-12 12:00:00 81
## 2 hourlyCalories_merged.csv 1503960366 2016-04-12 01:00:00 61
## 3 hourlyCalories_merged.csv 1503960366 2016-04-12 02:00:00 59
## 4 hourlyCalories_merged.csv 1503960366 2016-04-12 03:00:00 47
## 5 hourlyCalories_merged.csv 1503960366 2016-04-12 04:00:00 48
## 6 hourlyCalories_merged.csv 1503960366 2016-04-12 05:00:00 48
WeightLogInfo <- WeightLogInfo %>%
rename(DateTime = Date) %>%
mutate(DateTime = as.POSIXct(DateTime,format="%m/%d/%Y %H:%M:%S",tz=Sys.timezone()))
head(WeightLogInfo)
## # A tibble: 6 × 9
## `Table Names` Id DateTime WeightKg WeightPounds Fat BMI
## <chr> <chr> <dttm> <dbl> <dbl> <dbl> <dbl>
## 1 weightLogInfo_mer… 1503… 2016-04-05 11:59:59 53.3 118. 22 23.0
## 2 weightLogInfo_mer… 1927… 2016-04-10 06:33:26 130. 286. NA 46.2
## 3 weightLogInfo_mer… 2347… 2016-04-03 11:59:59 63.4 140. 10 24.8
## 4 weightLogInfo_mer… 2873… 2016-04-06 11:59:59 56.7 125. NA 21.5
## 5 weightLogInfo_mer… 2873… 2016-04-07 11:59:59 57.2 126. NA 21.6
## 6 weightLogInfo_mer… 2891… 2016-04-05 11:59:59 88.4 195. NA 25.0
## # ℹ 2 more variables: IsManualReport <lgl>, LogId <dbl>
minuteMETs <- minuteMETs %>%
rename(DateTime = ActivityMinute) %>%
mutate(DateTime = as.POSIXct(DateTime,format="%m/%d/%Y %H:%M:%S",tz=Sys.timezone()))
head(minuteMETs)
## # A tibble: 6 × 4
## `Table Names` Id DateTime METs
## <chr> <chr> <dttm> <dbl>
## 1 minuteMETsNarrow_merged.csv 1927972279 2016-03-25 02:48:00 10
## 2 minuteMETsNarrow_merged.csv 1927972279 2016-03-25 03:03:00 10
## 3 minuteMETsNarrow_merged.csv 1927972279 2016-03-25 03:07:00 10
## 4 minuteMETsNarrow_merged.csv 1927972279 2016-03-25 03:08:00 10
## 5 minuteMETsNarrow_merged.csv 1927972279 2016-03-25 03:11:00 10
## 6 minuteMETsNarrow_merged.csv 1927972279 2016-03-25 03:16:00 10
minuteSleep <- minuteSleep %>%
rename(DateTime = date) %>%
mutate(DateTime = as.POSIXct(DateTime,format="%m/%d/%Y %H:%M:%S",tz=Sys.timezone()))
head(minuteSleep)
## # A tibble: 6 × 5
## `Table Names` Id DateTime value logId
## <chr> <chr> <dttm> <dbl> <dbl>
## 1 minuteSleep_merged.csv 5577150313 2016-05-03 01:55:30 1 11560009516
## 2 minuteSleep_merged.csv 5577150313 2016-05-03 01:56:30 1 11560009516
## 3 minuteSleep_merged.csv 5577150313 2016-05-03 01:57:30 1 11560009516
## 4 minuteSleep_merged.csv 5577150313 2016-05-03 01:58:30 1 11560009516
## 5 minuteSleep_merged.csv 5577150313 2016-05-03 01:59:30 1 11560009516
## 6 minuteSleep_merged.csv 5577150313 2016-05-03 02:00:30 1 11560009516
heartrate <- heartrate %>%
rename(DateTime = Time) %>%
mutate(DateTime = as.POSIXct(DateTime,format="%m/%d/%Y %H:%M:%S",tz=Sys.timezone()))
head(heartrate)
## # A tibble: 6 × 3
## Id DateTime Value
## <chr> <dttm> <dbl>
## 1 2347167796 2016-03-29 10:49:30 65
## 2 2347167796 2016-03-29 10:49:45 65
## 3 2347167796 2016-03-29 10:49:50 63
## 4 2347167796 2016-03-29 10:50:05 63
## 5 2347167796 2016-03-29 10:50:20 63
## 6 2347167796 2016-03-29 10:50:30 62
SleepDay <- SleepDay %>%
rename(DateTime = SleepDay) %>%
mutate(DateTime = as.POSIXct(DateTime,format="%m/%d/%Y %H:%M:%S",tz=Sys.timezone()))
head(SleepDay)
## # A tibble: 6 × 5
## Id DateTime TotalSleepRecords TotalMinutesAsleep TotalTimeInBed
## <chr> <dttm> <dbl> <dbl> <dbl>
## 1 15039… 2016-04-12 12:00:00 1 327 346
## 2 15039… 2016-04-13 12:00:00 2 384 407
## 3 15039… 2016-04-15 12:00:00 1 412 442
## 4 15039… 2016-04-16 12:00:00 2 340 367
## 5 15039… 2016-04-17 12:00:00 1 700 712
## 6 15039… 2016-04-19 12:00:00 1 304 320
##3.2 Analyze Phase
3.2.1 Use of the Smart Device
For this case we require the data from “dailyActivity” and “minutesSleep”, also the Date field is important, we proceed to give the format require
minuteSleep$time <- format(as.POSIXct(minuteSleep$DateTime,format="%Y/%m/%d %H:%M:%S"),"%H:%M:%S")
minuteSleep$date <- format(as.POSIXct(minuteSleep$DateTime,format="%Y/%m/%d %H:%M:%S"),"%Y/%m/%d")
head(minuteSleep)
## # A tibble: 6 × 7
## `Table Names` Id DateTime value logId time date
## <chr> <chr> <dttm> <dbl> <dbl> <chr> <chr>
## 1 minuteSleep_merged.csv 55771503… 2016-05-03 01:55:30 1 1.16e10 01:5… 2016…
## 2 minuteSleep_merged.csv 55771503… 2016-05-03 01:56:30 1 1.16e10 01:5… 2016…
## 3 minuteSleep_merged.csv 55771503… 2016-05-03 01:57:30 1 1.16e10 01:5… 2016…
## 4 minuteSleep_merged.csv 55771503… 2016-05-03 01:58:30 1 1.16e10 01:5… 2016…
## 5 minuteSleep_merged.csv 55771503… 2016-05-03 01:59:30 1 1.16e10 01:5… 2016…
## 6 minuteSleep_merged.csv 55771503… 2016-05-03 02:00:30 1 1.16e10 02:0… 2016…
Now change the date field from “chr” to date format
minuteSleep$date <- as.Date(minuteSleep$date)
head(minuteSleep)
## # A tibble: 6 × 7
## `Table Names` Id DateTime value logId time date
## <chr> <chr> <dttm> <dbl> <dbl> <chr> <date>
## 1 minuteSleep_merged.c… 5577… 2016-05-03 01:55:30 1 1.16e10 01:5… 2016-05-03
## 2 minuteSleep_merged.c… 5577… 2016-05-03 01:56:30 1 1.16e10 01:5… 2016-05-03
## 3 minuteSleep_merged.c… 5577… 2016-05-03 01:57:30 1 1.16e10 01:5… 2016-05-03
## 4 minuteSleep_merged.c… 5577… 2016-05-03 01:58:30 1 1.16e10 01:5… 2016-05-03
## 5 minuteSleep_merged.c… 5577… 2016-05-03 01:59:30 1 1.16e10 01:5… 2016-05-03
## 6 minuteSleep_merged.c… 5577… 2016-05-03 02:00:30 1 1.16e10 02:0… 2016-05-03
Now we proceed to merge the data to Daily Activity as main source, so we use Id and date fields.
n_distinct(dailyActivity$Id)
## [1] 35
n_distinct(minuteSleep$Id)
## [1] 25
DailyAndSleep_Activity2 <- dailyActivity %>%
left_join(minuteSleep, by=c ("Id", "date"))
## Warning in left_join(., minuteSleep, by = c("Id", "date")): Detected an unexpected many-to-many relationship between `x` and `y`.
## ℹ Row 1 of `x` matches multiple rows in `y`.
## ℹ Row 17569 of `y` matches multiple rows in `x`.
## ℹ If a many-to-many relationship is expected, set `relationship =
## "many-to-many"` to silence this warning.
glimpse(DailyAndSleep_Activity2)
## Rows: 283,026
## Columns: 20
## $ Id <chr> "1503960366", "1503960366", "1503960366", "15…
## $ date <dttm> 2016-04-12, 2016-04-12, 2016-04-12, 2016-04-…
## $ TotalSteps <dbl> 13162, 13162, 13162, 13162, 13162, 13162, 131…
## $ TotalDistance <dbl> 8.5, 8.5, 8.5, 8.5, 8.5, 8.5, 8.5, 8.5, 8.5, …
## $ TrackerDistance <dbl> 8.5, 8.5, 8.5, 8.5, 8.5, 8.5, 8.5, 8.5, 8.5, …
## $ VeryActiveDistance <dbl> 1.88, 1.88, 1.88, 1.88, 1.88, 1.88, 1.88, 1.8…
## $ ModeratelyActiveDistance <dbl> 0.55, 0.55, 0.55, 0.55, 0.55, 0.55, 0.55, 0.5…
## $ LightActiveDistance <dbl> 6.06, 6.06, 6.06, 6.06, 6.06, 6.06, 6.06, 6.0…
## $ SedentaryActiveDistance <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …
## $ VeryActiveMinutes <dbl> 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 2…
## $ FairlyActiveMinutes <dbl> 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 1…
## $ LightlyActiveMinutes <dbl> 328, 328, 328, 328, 328, 328, 328, 328, 328, …
## $ SedentaryMinutes <dbl> 728, 728, 728, 728, 728, 728, 728, 728, 728, …
## $ Calories <dbl> 1985, 1985, 1985, 1985, 1985, 1985, 1985, 198…
## $ LoggedActivitiesDistance <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …
## $ `Table Names` <chr> "minuteSleep_merged.csv", "minuteSleep_merged…
## $ DateTime <dttm> 2016-04-12 02:49:30, 2016-04-12 02:50:30, 20…
## $ value <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, …
## $ logId <dbl> 11380564589, 11380564589, 11380564589, 113805…
## $ time <chr> "02:49:30", "02:50:30", "02:51:30", "02:52:30…
head(DailyAndSleep_Activity2)
## # A tibble: 6 × 20
## Id date TotalSteps TotalDistance TrackerDistance
## <chr> <dttm> <dbl> <dbl> <dbl>
## 1 1503960366 2016-04-12 00:00:00 13162 8.5 8.5
## 2 1503960366 2016-04-12 00:00:00 13162 8.5 8.5
## 3 1503960366 2016-04-12 00:00:00 13162 8.5 8.5
## 4 1503960366 2016-04-12 00:00:00 13162 8.5 8.5
## 5 1503960366 2016-04-12 00:00:00 13162 8.5 8.5
## 6 1503960366 2016-04-12 00:00:00 13162 8.5 8.5
## # ℹ 15 more variables: VeryActiveDistance <dbl>,
## # ModeratelyActiveDistance <dbl>, LightActiveDistance <dbl>,
## # SedentaryActiveDistance <dbl>, VeryActiveMinutes <dbl>,
## # FairlyActiveMinutes <dbl>, LightlyActiveMinutes <dbl>,
## # SedentaryMinutes <dbl>, Calories <dbl>, LoggedActivitiesDistance <dbl>,
## # `Table Names` <chr>, DateTime <dttm>, value <dbl>, logId <dbl>, time <chr>
n_distinct(DailyAndSleep_Activity2$Id)
## [1] 35
The data analyze include the months from March to May 2016, so the total days register must be 92 days, being this data equivalent to 100% or High Use Type, so we proceed with the next base for analysis:
*Data from March to May 2016, days per month, 31, 30 and 31; average 30.66 ≈ 31
*Totals days per Data from Mach-May is 92 days
Given that we proceed to identify by used per day as follow:
* high use - users who use their device between 1 and 21 days.
* moderate use - users who use their device between 22 and 60 days.
* low use - users who use their device between 61 and 92 days.
daily_use <- DailyAndSleep_Activity2 %>%
group_by(Id) %>%
summarise(days_used = n(),u_count_used = n_distinct(date)) %>%
mutate(usage = case_when(
days_used >= 1 & u_count_used <= 31 ~ "low use",
days_used >= 31 & u_count_used <= 60 ~ "moderate use",
days_used >= 61 & u_count_used <= 92 ~ "high use",
))
head(daily_use)
## # A tibble: 6 × 4
## Id days_used u_count_used usage
## <chr> <int> <int> <chr>
## 1 1503960366 15192 49 moderate use
## 2 1624580081 50 49 moderate use
## 3 1644430081 1419 40 moderate use
## 4 1844505072 4839 42 moderate use
## 5 1927972279 7071 42 moderate use
## 6 2022484408 43 42 moderate use
And create a percentage table
daily_use_percent <- daily_use %>%
group_by(usage) %>%
summarise(total = n()) %>%
mutate(totals = sum(total)) %>%
group_by(usage) %>%
summarise(total_percent = total / totals) %>%
mutate(labels = scales::percent(total_percent))
daily_use_percent$usage <- factor(daily_use_percent$usage, levels = c("high use", "moderate use", "low use"))
head(daily_use_percent)
## # A tibble: 3 × 3
## usage total_percent labels
## <fct> <dbl> <chr>
## 1 high use 0.0286 2.9%
## 2 low use 0.114 11.4%
## 3 moderate use 0.857 85.7%
And the it’s graphic representation
ggpie(data = daily_use_percent, x="total_percent", label = "labels",
lab.pos = "out",
fill = "usage", color = "white",
palette = c("#85e085","#e6e600", "#ffd480"))+
ggtitle(label = "Daily use of the Smart Device")+
theme(plot.title = element_text(hjust = 0.5, size = 14))
Analyzing the results
The majority of user that represent the 85.7% of the user use the smart device more than 22 day but less than 60
The second type of user is the “low user” that represent the 11.4%, and it’s use is from 1 day to 21 days of the total
The High use is the lowest percentage, 2.9%, that use the smart device more than 60 days
3.2.2 Use of the Smart Device during the day
Being more precise we want to see how many minutes do users wear their device per day, for that we proceed to merge the data set dailyActivity and daily_use, by Id field.
n_distinct(dailyActivity$Id)
## [1] 35
n_distinct(daily_use$Id)
## [1] 35
daily_use_merged <- merge(dailyActivity, daily_use, by=c ("Id"))
head(daily_use_merged)
## Id date TotalSteps TotalDistance TrackerDistance
## 1 1503960366 2016-04-12 13162 8.50 8.50
## 2 1503960366 2016-04-13 10735 6.97 6.97
## 3 1503960366 2016-04-14 10460 6.74 6.74
## 4 1503960366 2016-04-15 9762 6.28 6.28
## 5 1503960366 2016-04-16 12669 8.16 8.16
## 6 1503960366 2016-04-17 9705 6.48 6.48
## VeryActiveDistance ModeratelyActiveDistance LightActiveDistance
## 1 1.88 0.55 6.06
## 2 1.57 0.69 4.71
## 3 2.44 0.40 3.91
## 4 2.14 1.26 2.83
## 5 2.71 0.41 5.04
## 6 3.19 0.78 2.51
## SedentaryActiveDistance VeryActiveMinutes FairlyActiveMinutes
## 1 0 25 13
## 2 0 21 19
## 3 0 30 11
## 4 0 29 34
## 5 0 36 10
## 6 0 38 20
## LightlyActiveMinutes SedentaryMinutes Calories LoggedActivitiesDistance
## 1 328 728 1985 0
## 2 217 776 1797 0
## 3 181 1218 1776 0
## 4 209 726 1745 0
## 5 221 773 1863 0
## 6 164 539 1728 0
## days_used u_count_used usage
## 1 15192 49 moderate use
## 2 15192 49 moderate use
## 3 15192 49 moderate use
## 4 15192 49 moderate use
## 5 15192 49 moderate use
## 6 15192 49 moderate use
n_distinct(daily_use_merged$Id)
## [1] 35
Now we calculate the minutes that the device is worn by the users.
We need to create a new data frame calculating the total amount of minutes users wore the device every day and creating three different categories:
*All day - device was worn all day.
*More than half day - device was worn more than half of the day.
*Less than half day - device was worn less than half of the day.
minutes_worn <- daily_use_merged %>%
mutate(total_minutes_worn = VeryActiveMinutes+FairlyActiveMinutes+LightlyActiveMinutes+SedentaryMinutes)%>%
mutate (percent_minutes_worn = (total_minutes_worn/1440)*100) %>%
mutate (worn = case_when(
percent_minutes_worn == 100 ~ "All day",
percent_minutes_worn < 100 & percent_minutes_worn >= 50~ "More than half day",
percent_minutes_worn < 50 & percent_minutes_worn > 0 ~ "Less than half day"
))
head(minutes_worn)
## Id date TotalSteps TotalDistance TrackerDistance
## 1 1503960366 2016-04-12 13162 8.50 8.50
## 2 1503960366 2016-04-13 10735 6.97 6.97
## 3 1503960366 2016-04-14 10460 6.74 6.74
## 4 1503960366 2016-04-15 9762 6.28 6.28
## 5 1503960366 2016-04-16 12669 8.16 8.16
## 6 1503960366 2016-04-17 9705 6.48 6.48
## VeryActiveDistance ModeratelyActiveDistance LightActiveDistance
## 1 1.88 0.55 6.06
## 2 1.57 0.69 4.71
## 3 2.44 0.40 3.91
## 4 2.14 1.26 2.83
## 5 2.71 0.41 5.04
## 6 3.19 0.78 2.51
## SedentaryActiveDistance VeryActiveMinutes FairlyActiveMinutes
## 1 0 25 13
## 2 0 21 19
## 3 0 30 11
## 4 0 29 34
## 5 0 36 10
## 6 0 38 20
## LightlyActiveMinutes SedentaryMinutes Calories LoggedActivitiesDistance
## 1 328 728 1985 0
## 2 217 776 1797 0
## 3 181 1218 1776 0
## 4 209 726 1745 0
## 5 221 773 1863 0
## 6 164 539 1728 0
## days_used u_count_used usage total_minutes_worn percent_minutes_worn
## 1 15192 49 moderate use 1094 75.97222
## 2 15192 49 moderate use 1033 71.73611
## 3 15192 49 moderate use 1440 100.00000
## 4 15192 49 moderate use 998 69.30556
## 5 15192 49 moderate use 1040 72.22222
## 6 15192 49 moderate use 761 52.84722
## worn
## 1 More than half day
## 2 More than half day
## 3 All day
## 4 More than half day
## 5 More than half day
## 6 More than half day
The percentage representation of minutes worn per category
minutes_worn_percent<- minutes_worn%>%
group_by(worn) %>%
summarise(total = n()) %>%
mutate(totals = sum(total)) %>%
group_by(worn) %>%
summarise(total_percent = total / totals) %>%
mutate(labels = scales::percent(total_percent))
head(minutes_worn_percent)
## # A tibble: 3 × 3
## worn total_percent labels
## <chr> <dbl> <chr>
## 1 All day 0.509 50.9%
## 2 Less than half day 0.0387 3.9%
## 3 More than half day 0.452 45.2%
Graphic representation of the minutes worn per category
ggpie(data = minutes_worn_percent, x="total_percent", label = "labels",
lab.pos = "out",
fill = "worn", color = "white",
palette = c("#004d99", "#3399ff", "#cce6ff"))+
ggtitle(label = "Time Worn per Day")+
theme(plot.title = element_text(hjust = 0.5, size = 14))
Per this data we can conclude
And then proceed to review for each Type of user it’s minutes worn per category, tables and chart.
minutes_worn_highuse <- minutes_worn%>%
filter (usage == "high use")%>%
group_by(worn) %>%
summarise(total = n()) %>%
mutate(totals = sum(total)) %>%
group_by(worn) %>%
summarise(total_percent = total / totals) %>%
mutate(labels = scales::percent(total_percent))
minutes_worn_moduse <- minutes_worn%>%
filter(usage == "moderate use") %>%
group_by(worn) %>%
summarise(total = n()) %>%
mutate(totals = sum(total)) %>%
group_by(worn) %>%
summarise(total_percent = total / totals) %>%
mutate(labels = scales::percent(total_percent))
minutes_worn_lowuse <- minutes_worn%>%
filter (usage == "low use") %>%
group_by(worn) %>%
summarise(total = n()) %>%
mutate(totals = sum(total)) %>%
group_by(worn) %>%
summarise(total_percent = total / totals) %>%
mutate(labels = scales::percent(total_percent))
minutes_worn_highuse$worn <- factor(minutes_worn_highuse$worn, levels = c("All day", "More than half day", "Less than half day"))
minutes_worn_percent$worn <- factor(minutes_worn_percent$worn, levels = c("All day", "More than half day", "Less than half day"))
minutes_worn_moduse$worn <- factor(minutes_worn_moduse$worn, levels = c("All day", "More than half day", "Less than half day"))
minutes_worn_lowuse$worn <- factor(minutes_worn_lowuse$worn, levels = c("All day", "More than half day", "Less than half day"))
head(minutes_worn_percent)
## # A tibble: 3 × 3
## worn total_percent labels
## <fct> <dbl> <chr>
## 1 All day 0.509 50.9%
## 2 Less than half day 0.0387 3.9%
## 3 More than half day 0.452 45.2%
head(minutes_worn_highuse)
## # A tibble: 3 × 3
## worn total_percent labels
## <fct> <dbl> <chr>
## 1 All day 0.571 57%
## 2 Less than half day 0.0159 2%
## 3 More than half day 0.413 41%
head(minutes_worn_moduse)
## # A tibble: 3 × 3
## worn total_percent labels
## <fct> <dbl> <chr>
## 1 All day 0.480 48.01%
## 2 Less than half day 0.0414 4.14%
## 3 More than half day 0.479 47.85%
head(minutes_worn_lowuse)
## # A tibble: 3 × 3
## worn total_percent labels
## <fct> <dbl> <chr>
## 1 All day 0.923 92.3%
## 2 Less than half day 0.0128 1.3%
## 3 More than half day 0.0641 6.4%
And its graphic representation
ggpie(data = minutes_worn_highuse, x="total_percent", label = "labels",
lab.pos = "out",
fill = "worn", color = "white",
palette = c("#004d99", "#3399ff", "#cce6ff"))+
ggtitle(label = "High Use - Users")+
theme(plot.title = element_text(hjust = 0.5, size = 14))
ggpie(data = minutes_worn_moduse, x="total_percent", label = "labels",
lab.pos = "out",
fill = "worn", color = "white",
palette = c("#004d99", "#3399ff", "#cce6ff"))+
ggtitle(label = "Moderate Use - Users")+
theme(plot.title = element_text(hjust = 0.5, size = 14))
ggpie(data = minutes_worn_lowuse, x="total_percent", label = "labels",
lab.pos = "out",
fill = "worn", color = "white",
palette = c("#004d99", "#3399ff", "#cce6ff"))+
ggtitle(label = "Low Use - Users")+
theme(plot.title = element_text(hjust = 0.5, size = 14))
With this:
The High Users, use their device more than half of the day, or all day
The moderate users, use their device more than half of the day
Low Users use the device all day
So even the device is on use, the user are not very active.
3.2.2 Type of users per activity level
For that we proceed to create a Activity level category definition.
Activity level by Steps:
*https://www.medicinenet.com/how_many_steps_a_day_is_considered_active/article.htm*
*Sedentary: Less than 5,000 steps daily
*Low active: About 5,000 to 7,499 steps daily
*Somewhat active: About 7,500 to 9,999 steps daily
*Active: More than 10,000 steps daily
*Highly active: More than 12,500 steps daily
For this we need the table previously create “DailyAndSleep_Activity2” and the SleepDay Data in order to have the sedentary time too, and give priority a Id from DailyAndSleep_Activity2.
n_distinct(SleepDay$Id)
## [1] 24
n_distinct(DailyAndSleep_Activity2$Id)
## [1] 35
DailyAndSleep_Activity3 <- DailyAndSleep_Activity2 %>%
left_join(SleepDay, by=c ("Id"))
## Warning in left_join(., SleepDay, by = c("Id")): Detected an unexpected many-to-many relationship between `x` and `y`.
## ℹ Row 1 of `x` matches multiple rows in `y`.
## ℹ Row 1 of `y` matches multiple rows in `x`.
## ℹ If a many-to-many relationship is expected, set `relationship =
## "many-to-many"` to silence this warning.
glimpse(DailyAndSleep_Activity3)
## Rows: 6,798,724
## Columns: 24
## $ Id <chr> "1503960366", "1503960366", "1503960366", "15…
## $ date <dttm> 2016-04-12, 2016-04-12, 2016-04-12, 2016-04-…
## $ TotalSteps <dbl> 13162, 13162, 13162, 13162, 13162, 13162, 131…
## $ TotalDistance <dbl> 8.5, 8.5, 8.5, 8.5, 8.5, 8.5, 8.5, 8.5, 8.5, …
## $ TrackerDistance <dbl> 8.5, 8.5, 8.5, 8.5, 8.5, 8.5, 8.5, 8.5, 8.5, …
## $ VeryActiveDistance <dbl> 1.88, 1.88, 1.88, 1.88, 1.88, 1.88, 1.88, 1.8…
## $ ModeratelyActiveDistance <dbl> 0.55, 0.55, 0.55, 0.55, 0.55, 0.55, 0.55, 0.5…
## $ LightActiveDistance <dbl> 6.06, 6.06, 6.06, 6.06, 6.06, 6.06, 6.06, 6.0…
## $ SedentaryActiveDistance <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …
## $ VeryActiveMinutes <dbl> 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 2…
## $ FairlyActiveMinutes <dbl> 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 1…
## $ LightlyActiveMinutes <dbl> 328, 328, 328, 328, 328, 328, 328, 328, 328, …
## $ SedentaryMinutes <dbl> 728, 728, 728, 728, 728, 728, 728, 728, 728, …
## $ Calories <dbl> 1985, 1985, 1985, 1985, 1985, 1985, 1985, 198…
## $ LoggedActivitiesDistance <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …
## $ `Table Names` <chr> "minuteSleep_merged.csv", "minuteSleep_merged…
## $ DateTime.x <dttm> 2016-04-12 02:49:30, 2016-04-12 02:49:30, 20…
## $ value <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, …
## $ logId <dbl> 11380564589, 11380564589, 11380564589, 113805…
## $ time <chr> "02:49:30", "02:49:30", "02:49:30", "02:49:30…
## $ DateTime.y <dttm> 2016-04-12 12:00:00, 2016-04-13 12:00:00, 20…
## $ TotalSleepRecords <dbl> 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, …
## $ TotalMinutesAsleep <dbl> 327, 384, 412, 340, 700, 304, 360, 325, 361, …
## $ TotalTimeInBed <dbl> 346, 407, 442, 367, 712, 320, 377, 364, 384, …
head(DailyAndSleep_Activity3)
## # A tibble: 6 × 24
## Id date TotalSteps TotalDistance TrackerDistance
## <chr> <dttm> <dbl> <dbl> <dbl>
## 1 1503960366 2016-04-12 00:00:00 13162 8.5 8.5
## 2 1503960366 2016-04-12 00:00:00 13162 8.5 8.5
## 3 1503960366 2016-04-12 00:00:00 13162 8.5 8.5
## 4 1503960366 2016-04-12 00:00:00 13162 8.5 8.5
## 5 1503960366 2016-04-12 00:00:00 13162 8.5 8.5
## 6 1503960366 2016-04-12 00:00:00 13162 8.5 8.5
## # ℹ 19 more variables: VeryActiveDistance <dbl>,
## # ModeratelyActiveDistance <dbl>, LightActiveDistance <dbl>,
## # SedentaryActiveDistance <dbl>, VeryActiveMinutes <dbl>,
## # FairlyActiveMinutes <dbl>, LightlyActiveMinutes <dbl>,
## # SedentaryMinutes <dbl>, Calories <dbl>, LoggedActivitiesDistance <dbl>,
## # `Table Names` <chr>, DateTime.x <dttm>, value <dbl>, logId <dbl>,
## # time <chr>, DateTime.y <dttm>, TotalSleepRecords <dbl>, …
Adding the average for the field of TotalSteps, Calories, and TotalMinutesAsleep
daily_average <- DailyAndSleep_Activity3 %>%
group_by(Id) %>%
summarise (mean_daily_steps = mean(TotalSteps), mean_daily_calories = mean(Calories), mean_daily_sleep = mean(TotalMinutesAsleep))
head(daily_average)
## # A tibble: 6 × 4
## Id mean_daily_steps mean_daily_calories mean_daily_sleep
## <chr> <dbl> <dbl> <dbl>
## 1 1503960366 11966. 1834. 360.
## 2 1624580081 5167. 1434. NA
## 3 1644430081 6175. 2779. 294
## 4 1844505072 3562. 1688. 652
## 5 1927972279 1543. 2108. 417
## 6 2022484408 11595. 2500. NA
User type definition by steps
user_type <- daily_average %>%
mutate(user_type = case_when(
mean_daily_steps < 5000 ~ "sedentary",
mean_daily_steps >= 5000 & mean_daily_steps < 7499 ~ "lightly active",
mean_daily_steps >= 7500 & mean_daily_steps < 9999 ~ "fairly active",
mean_daily_steps >= 10000 ~ "very active"
))
head(user_type)
## # A tibble: 6 × 5
## Id mean_daily_steps mean_daily_calories mean_daily_sleep user_type
## <chr> <dbl> <dbl> <dbl> <chr>
## 1 1503960366 11966. 1834. 360. very active
## 2 1624580081 5167. 1434. NA lightly acti…
## 3 1644430081 6175. 2779. 294 lightly acti…
## 4 1844505072 3562. 1688. 652 sedentary
## 5 1927972279 1543. 2108. 417 sedentary
## 6 2022484408 11595. 2500. NA very active
Remove NA
user_type <- user_type %>%
distinct() %>%
drop_na()
head(user_type)
## # A tibble: 6 × 5
## Id mean_daily_steps mean_daily_calories mean_daily_sleep user_type
## <chr> <dbl> <dbl> <dbl> <chr>
## 1 1503960366 11966. 1834. 360. very active
## 2 1644430081 6175. 2779. 294 lightly acti…
## 3 1844505072 3562. 1688. 652 sedentary
## 4 1927972279 1543. 2108. 417 sedentary
## 5 2026352035 4814. 1471. 506. sedentary
## 6 2320127002 4768. 1752. 61 sedentary
Now that we have a new column with the user type we will create a data frame with the percentage of each user type to better visualize them on a graph.
user_type_percent <- user_type %>%
group_by(user_type) %>%
summarise(total = n()) %>%
mutate(totals = sum(total)) %>%
group_by(user_type) %>%
summarise(total_percent = total / totals) %>%
mutate(labels = scales::percent(total_percent))
user_type_percent$user_type <- factor(user_type_percent$user_type , levels = c("very active", "fairly active", "lightly active", "sedentary"))
head(user_type_percent)
## # A tibble: 4 × 3
## user_type total_percent labels
## <fct> <dbl> <chr>
## 1 fairly active 0.292 29.2%
## 2 lightly active 0.208 20.8%
## 3 sedentary 0.25 25.0%
## 4 very active 0.25 25.0%
ggpie(data = user_type_percent, x="total_percent", label = "labels",
lab.pos = "out",
fill = "user_type", color = "white",
palette = c("#85e085","#e6e600", "#ffd480", "#ff8080"))+
ggtitle(label = "User Type Distribution")+
theme(plot.title = element_text(hjust = 0.5, size = 14))
The activity distribution per user type, is very near of each other. the device is worn most of the half of a day or all day, so the data is reliable. however the use of the device is not a factor that increase its physical activity.
3.2.3 Steps and Sleep Distribution by Weekday
First we are going to proceed to add the weekday to our DailyAndSleep_Activity3 data
head(DailyAndSleep_Activity3)
## # A tibble: 6 × 24
## Id date TotalSteps TotalDistance TrackerDistance
## <chr> <dttm> <dbl> <dbl> <dbl>
## 1 1503960366 2016-04-12 00:00:00 13162 8.5 8.5
## 2 1503960366 2016-04-12 00:00:00 13162 8.5 8.5
## 3 1503960366 2016-04-12 00:00:00 13162 8.5 8.5
## 4 1503960366 2016-04-12 00:00:00 13162 8.5 8.5
## 5 1503960366 2016-04-12 00:00:00 13162 8.5 8.5
## 6 1503960366 2016-04-12 00:00:00 13162 8.5 8.5
## # ℹ 19 more variables: VeryActiveDistance <dbl>,
## # ModeratelyActiveDistance <dbl>, LightActiveDistance <dbl>,
## # SedentaryActiveDistance <dbl>, VeryActiveMinutes <dbl>,
## # FairlyActiveMinutes <dbl>, LightlyActiveMinutes <dbl>,
## # SedentaryMinutes <dbl>, Calories <dbl>, LoggedActivitiesDistance <dbl>,
## # `Table Names` <chr>, DateTime.x <dttm>, value <dbl>, logId <dbl>,
## # time <chr>, DateTime.y <dttm>, TotalSleepRecords <dbl>, …
weekday_steps_sleep <- DailyAndSleep_Activity3 %>%
mutate(weekday = weekdays(date))
weekday_steps_sleep$weekday <-ordered(weekday_steps_sleep$weekday, levels=c("Monday", "Tuesday", "Wednesday", "Thursday",
"Friday", "Saturday", "Sunday"))
head(weekday_steps_sleep)
## # A tibble: 6 × 25
## Id date TotalSteps TotalDistance TrackerDistance
## <chr> <dttm> <dbl> <dbl> <dbl>
## 1 1503960366 2016-04-12 00:00:00 13162 8.5 8.5
## 2 1503960366 2016-04-12 00:00:00 13162 8.5 8.5
## 3 1503960366 2016-04-12 00:00:00 13162 8.5 8.5
## 4 1503960366 2016-04-12 00:00:00 13162 8.5 8.5
## 5 1503960366 2016-04-12 00:00:00 13162 8.5 8.5
## 6 1503960366 2016-04-12 00:00:00 13162 8.5 8.5
## # ℹ 20 more variables: VeryActiveDistance <dbl>,
## # ModeratelyActiveDistance <dbl>, LightActiveDistance <dbl>,
## # SedentaryActiveDistance <dbl>, VeryActiveMinutes <dbl>,
## # FairlyActiveMinutes <dbl>, LightlyActiveMinutes <dbl>,
## # SedentaryMinutes <dbl>, Calories <dbl>, LoggedActivitiesDistance <dbl>,
## # `Table Names` <chr>, DateTime.x <dttm>, value <dbl>, logId <dbl>,
## # time <chr>, DateTime.y <dttm>, TotalSleepRecords <dbl>, …
Now we proceed to group by weekday
weekday_steps_sleep$TotalMinutesAsleep <- as.numeric(weekday_steps_sleep$TotalMinutesAsleep)
weekday_steps_sleep <- weekday_steps_sleep %>%
distinct() %>%
drop_na()
head(weekday_steps_sleep)
## # A tibble: 6 × 25
## Id date TotalSteps TotalDistance TrackerDistance
## <chr> <dttm> <dbl> <dbl> <dbl>
## 1 1503960366 2016-04-12 00:00:00 13162 8.5 8.5
## 2 1503960366 2016-04-12 00:00:00 13162 8.5 8.5
## 3 1503960366 2016-04-12 00:00:00 13162 8.5 8.5
## 4 1503960366 2016-04-12 00:00:00 13162 8.5 8.5
## 5 1503960366 2016-04-12 00:00:00 13162 8.5 8.5
## 6 1503960366 2016-04-12 00:00:00 13162 8.5 8.5
## # ℹ 20 more variables: VeryActiveDistance <dbl>,
## # ModeratelyActiveDistance <dbl>, LightActiveDistance <dbl>,
## # SedentaryActiveDistance <dbl>, VeryActiveMinutes <dbl>,
## # FairlyActiveMinutes <dbl>, LightlyActiveMinutes <dbl>,
## # SedentaryMinutes <dbl>, Calories <dbl>, LoggedActivitiesDistance <dbl>,
## # `Table Names` <chr>, DateTime.x <dttm>, value <dbl>, logId <dbl>,
## # time <chr>, DateTime.y <dttm>, TotalSleepRecords <dbl>, …
weekday_steps_sleep <- weekday_steps_sleep%>%
group_by(weekday) %>%
summarize (daily_steps = mean(TotalSteps), daily_sleep = mean(TotalMinutesAsleep))
head(weekday_steps_sleep)
## # A tibble: 6 × 3
## weekday daily_steps daily_sleep
## <ord> <dbl> <dbl>
## 1 Monday 8930. 432.
## 2 Tuesday 7957. 427.
## 3 Wednesday 8241. 434.
## 4 Thursday 8309. 431.
## 5 Friday 8361. 431.
## 6 Saturday 8650. 432.
Plot data as bar chart per weekday, with goal of 7500 steps per day and a std of 8 hours of sleep (480 minutes)
ggarrange(
ggplot(weekday_steps_sleep) +
geom_col(aes(weekday, daily_steps), fill = "#006699") +
geom_hline(yintercept = 7500) +
labs(title = "Daily steps per weekday", x= "", y = "") +
theme(axis.text.x = element_text(angle = 45,vjust = 0.5, hjust = 1)),
ggplot(weekday_steps_sleep, aes(weekday, daily_sleep)) +
geom_col(fill = "#85e0e0") +
geom_hline(yintercept = 480) +
labs(title = "Minutes asleep per weekday", x= "", y = "") +
theme(axis.text.x = element_text(angle = 45,vjust = 0.5, hjust = 1))
)
Now will be review the steps throughout the data
head(hourlySteps)
## # A tibble: 6 × 4
## `Table Names` Id date_time StepTotal
## <chr> <chr> <dttm> <dbl>
## 1 hourlySteps_merged.csv 1503960366 2016-03-12 00:00:00 0
## 2 hourlySteps_merged.csv 1503960366 2016-03-12 01:00:00 0
## 3 hourlySteps_merged.csv 1503960366 2016-03-12 02:00:00 0
## 4 hourlySteps_merged.csv 1503960366 2016-03-12 03:00:00 0
## 5 hourlySteps_merged.csv 1503960366 2016-03-12 04:00:00 0
## 6 hourlySteps_merged.csv 1503960366 2016-03-12 05:00:00 0
hourlySteps <- hourlySteps %>%
separate(date_time, into = c("date", "time"), sep= " ") %>%
mutate(date = ymd(date))
hourlySteps <- hourlySteps %>%
drop_na()
head(hourlySteps)
## # A tibble: 6 × 5
## `Table Names` Id date time StepTotal
## <chr> <chr> <date> <chr> <dbl>
## 1 hourlySteps_merged.csv 1503960366 2016-03-12 01:00:00 0
## 2 hourlySteps_merged.csv 1503960366 2016-03-12 02:00:00 0
## 3 hourlySteps_merged.csv 1503960366 2016-03-12 03:00:00 0
## 4 hourlySteps_merged.csv 1503960366 2016-03-12 04:00:00 0
## 5 hourlySteps_merged.csv 1503960366 2016-03-12 05:00:00 0
## 6 hourlySteps_merged.csv 1503960366 2016-03-12 06:00:00 0
plot looks like
hourlySteps %>%
group_by(time) %>%
summarize(average_steps = mean(StepTotal)) %>%
ggplot() +
geom_col(mapping = aes(x=time, y = average_steps, fill = average_steps)) +
labs(title = "Hourly steps throughout the day", x="", y="") +
scale_fill_gradient(low = "green", high = "red")+
theme(axis.text.x = element_text(angle = 90))
The most active hour are mid day, can be given the lunch time and at the
afternoon, after work.
3.2.4 Correlations
We will review the correlation between steps and calories
ggplot(DailyAndSleep_Activity3, aes(x = TotalSteps, y = Calories)) +
geom_point() +
geom_smooth(color = "red") +
labs(title = "Daily Steps vs Calories", x="Daily Steps", y="Calories") +
theme(panel.background = element_blank())
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
Per our plots:
We can see a positive correlation between steps ans calories burned. is well know that walking helped to burn calories, however is not a good indicator of loosing weight
“Bellabeat is a women’s wellness company that has helped millions of women track their cycle, pregnancies, and live more in sync with their cycles” By https://bellabeat.com/about-us/
Given that In order to help Bellabeat, based on the data results, first we recommend expands the data analysis,and in order to have additional information, the demographic data will be important to analyze the trending on young-adult women, and create a strategic marketing for these niche.
Given that, we give the next recommendation to BellaBeat app:
Most of the user use their device, so the design brand is key for customer interests.