This is the optional capstone project for the completion of the Google Data Analysis Certificate. I have chosen the Case study 2 which is about analyzing competition data of Bellabeat health products. we will go into the scenario and details in the next steps.
You are a junior data analyst working on the marketing analyst team at Bellabeat, a high-tech manufacturer of health-focused products for women. Bellabeat is a successful small company, but they have the potential to become a larger player in the global smart device market. Urška Sršen, cofounder and Chief Creative Officer of Bellabeat, believes that analyzing smart device fitness data could help unlock new growth opportunities for the company.
You have been asked to focus on one of Bellabeat’s products and analyze smart device data to gain insight into how consumers are using their smart devices. The insights you discover will then help guide marketing strategy for the company. You will present your analysis to the Bellabeat executive team along with your high-level recommendations for Bellabeat’s marketing strategy.
install.packages("vctrs",repos = "http://cran.us.r-project.org")
## Installing package into 'C:/Users/George Karam/AppData/Local/R/win-library/4.2'
## (as 'lib' is unspecified)
## Warning: cannot remove prior installation of package 'vctrs'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): problem copying
## C:\Users\George
## Karam\AppData\Local\R\win-library\4.2\00LOCK\vctrs\libs\x64\vctrs.dll to
## C:\Users\George Karam\AppData\Local\R\win-library\4.2\vctrs\libs\x64\vctrs.dll:
## Permission denied
## Warning: restored 'vctrs'
install.packages("tidyverse",repos = "http://cran.us.r-project.org")
## Installing package into 'C:/Users/George Karam/AppData/Local/R/win-library/4.2'
## (as 'lib' is unspecified)
## also installing the dependencies 'conflicted', 'cli', 'dplyr', 'forcats', 'ggplot2', 'lubridate', 'readr', 'readxl'
## Warning: cannot remove prior installation of package 'cli'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): problem copying
## C:\Users\George
## Karam\AppData\Local\R\win-library\4.2\00LOCK\cli\libs\x64\cli.dll to
## C:\Users\George Karam\AppData\Local\R\win-library\4.2\cli\libs\x64\cli.dll:
## Permission denied
## Warning: restored 'cli'
## Warning: cannot remove prior installation of package 'dplyr'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): problem copying
## C:\Users\George
## Karam\AppData\Local\R\win-library\4.2\00LOCK\dplyr\libs\x64\dplyr.dll to
## C:\Users\George Karam\AppData\Local\R\win-library\4.2\dplyr\libs\x64\dplyr.dll:
## Permission denied
## Warning: restored 'dplyr'
install.packages("tidyr",repos = "http://cran.us.r-project.org")
## Installing package into 'C:/Users/George Karam/AppData/Local/R/win-library/4.2'
## (as 'lib' is unspecified)
install.packages("ggplot2",repos = "http://cran.us.r-project.org")
## Installing package into 'C:/Users/George Karam/AppData/Local/R/win-library/4.2'
## (as 'lib' is unspecified)
install.packages("dplyr",repos = "http://cran.us.r-project.org")
## Installing package into 'C:/Users/George Karam/AppData/Local/R/win-library/4.2'
## (as 'lib' is unspecified)
## Warning: cannot remove prior installation of package 'dplyr'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): problem copying
## C:\Users\George
## Karam\AppData\Local\R\win-library\4.2\00LOCK\dplyr\libs\x64\dplyr.dll to
## C:\Users\George Karam\AppData\Local\R\win-library\4.2\dplyr\libs\x64\dplyr.dll:
## Permission denied
## Warning: restored 'dplyr'
install.packages("lubridate",repos = "http://cran.us.r-project.org")
## Installing package into 'C:/Users/George Karam/AppData/Local/R/win-library/4.2'
## (as 'lib' is unspecified)
install.packages("janitor",repos = "http://cran.us.r-project.org")
## Installing package into 'C:/Users/George Karam/AppData/Local/R/win-library/4.2'
## (as 'lib' is unspecified)
install.packages("ggVennDiagram",repos = "http://cran.us.r-project.org")
## Installing package into 'C:/Users/George Karam/AppData/Local/R/win-library/4.2'
## (as 'lib' is unspecified)
install.packages("plotrix",repos = "http://cran.us.r-project.org")
## Installing package into 'C:/Users/George Karam/AppData/Local/R/win-library/4.2'
## (as 'lib' is unspecified)
install.packages("corrplot",repos = "http://cran.us.r-project.org")
## Installing package into 'C:/Users/George Karam/AppData/Local/R/win-library/4.2'
## (as 'lib' is unspecified)
library(vctrs)
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.0.10 ✔ readr 2.1.4
## ✔ forcats 1.0.0 ✔ stringr 1.5.0
## ✔ ggplot2 3.4.1 ✔ tibble 3.1.8
## ✔ lubridate 1.9.2 ✔ tidyr 1.3.0
## ✔ purrr 1.0.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::data_frame() masks tibble::data_frame(), vctrs::data_frame()
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errors
library(tidyr)
library(ggplot2)
library(lubridate)
library(dbplyr)
##
## Attaching package: 'dbplyr'
##
## The following objects are masked from 'package:dplyr':
##
## ident, sql
library(janitor)
##
## Attaching package: 'janitor'
##
## The following objects are masked from 'package:stats':
##
## chisq.test, fisher.test
library(plotrix)
library(ggVennDiagram)
library(corrplot)
## corrplot 0.92 loaded
The Dataset provided is from Kaggle and is the FitBit Fitness Tracker Data (CC0: Public Domain, dataset made available through Mobius). The Data is from thirty eligible fitibit users and contains information about daily activity, sleep, weight and heart rate.
activity_users <- read.csv("dailyActivity_merged.csv")
sleep_users <- read.csv("sleepDay_merged.csv")
weight_log_users <-read.csv("weightLogInfo_merged.csv")
heart_rate <- read.csv("heartrate_seconds_merged.csv")
Taking a look at the data.
head(activity_users)
## Id ActivityDate TotalSteps TotalDistance TrackerDistance
## 1 1503960366 4/12/2016 13162 8.50 8.50
## 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
## LoggedActivitiesDistance VeryActiveDistance ModeratelyActiveDistance
## 1 0 1.88 0.55
## 2 0 1.57 0.69
## 3 0 2.44 0.40
## 4 0 2.14 1.26
## 5 0 2.71 0.41
## 6 0 3.19 0.78
## LightActiveDistance SedentaryActiveDistance VeryActiveMinutes
## 1 6.06 0 25
## 2 4.71 0 21
## 3 3.91 0 30
## 4 2.83 0 29
## 5 5.04 0 36
## 6 2.51 0 38
## FairlyActiveMinutes LightlyActiveMinutes SedentaryMinutes Calories
## 1 13 328 728 1985
## 2 19 217 776 1797
## 3 11 181 1218 1776
## 4 34 209 726 1745
## 5 10 221 773 1863
## 6 20 164 539 1728
head(sleep_users)
## Id SleepDay TotalSleepRecords TotalMinutesAsleep
## 1 1503960366 4/12/2016 12:00:00 AM 1 327
## 2 1503960366 4/13/2016 12:00:00 AM 2 384
## 3 1503960366 4/15/2016 12:00:00 AM 1 412
## 4 1503960366 4/16/2016 12:00:00 AM 2 340
## 5 1503960366 4/17/2016 12:00:00 AM 1 700
## 6 1503960366 4/19/2016 12:00:00 AM 1 304
## TotalTimeInBed
## 1 346
## 2 407
## 3 442
## 4 367
## 5 712
## 6 320
head(weight_log_users)
## Id Date WeightKg WeightPounds Fat BMI
## 1 1503960366 5/2/2016 11:59:59 PM 52.6 115.9631 22 22.65
## 2 1503960366 5/3/2016 11:59:59 PM 52.6 115.9631 NA 22.65
## 3 1927972279 4/13/2016 1:08:52 AM 133.5 294.3171 NA 47.54
## 4 2873212765 4/21/2016 11:59:59 PM 56.7 125.0021 NA 21.45
## 5 2873212765 5/12/2016 11:59:59 PM 57.3 126.3249 NA 21.69
## 6 4319703577 4/17/2016 11:59:59 PM 72.4 159.6147 25 27.45
## IsManualReport LogId
## 1 True 1.462234e+12
## 2 True 1.462320e+12
## 3 False 1.460510e+12
## 4 True 1.461283e+12
## 5 True 1.463098e+12
## 6 True 1.460938e+12
head(heart_rate)
## Id Time Value
## 1 2022484408 4/12/2016 7:21:00 AM 97
## 2 2022484408 4/12/2016 7:21:05 AM 102
## 3 2022484408 4/12/2016 7:21:10 AM 105
## 4 2022484408 4/12/2016 7:21:20 AM 103
## 5 2022484408 4/12/2016 7:21:25 AM 101
## 6 2022484408 4/12/2016 7:22:05 AM 95
colnames(activity_users)
## [1] "Id" "ActivityDate"
## [3] "TotalSteps" "TotalDistance"
## [5] "TrackerDistance" "LoggedActivitiesDistance"
## [7] "VeryActiveDistance" "ModeratelyActiveDistance"
## [9] "LightActiveDistance" "SedentaryActiveDistance"
## [11] "VeryActiveMinutes" "FairlyActiveMinutes"
## [13] "LightlyActiveMinutes" "SedentaryMinutes"
## [15] "Calories"
colnames(sleep_users)
## [1] "Id" "SleepDay" "TotalSleepRecords"
## [4] "TotalMinutesAsleep" "TotalTimeInBed"
colnames(weight_log_users)
## [1] "Id" "Date" "WeightKg" "WeightPounds"
## [5] "Fat" "BMI" "IsManualReport" "LogId"
colnames(heart_rate)
## [1] "Id" "Time" "Value"
n_distinct(activity_users$Id)
## [1] 33
n_distinct(sleep_users$Id)
## [1] 24
n_distinct(weight_log_users$Id)
## [1] 8
n_distinct(heart_rate$Id)
## [1] 14
First impressions about the data is that it’s very limited and incomplete. the data is supposed to represent 30 users but we identified 33 distinct ids in the daily activity table, and not all users are using all the features of the smart device.
Here we will clean the 4 different data frames we will be working with. we will convert all column names to snake_case make sure every row is distinct. We will use mutate to add new columns to summarize some data and standardize dates to be able to merge later on. And we will select which variables we want to work with. and we will print our findings.
activity_cleaned <- activity_users %>%
clean_names() %>%
distinct() %>%
mutate(total_active_minutes =
very_active_minutes + fairly_active_minutes +
lightly_active_minutes ) %>%
mutate(date_new = as.Date(mdy(activity_date))) %>%
mutate(id = as.character(id)) %>%
select(id, date_new, total_steps, total_active_minutes,sedentary_minutes, calories)
print(paste0("Number of rows in Activity Table before cleaning: " , nrow(activity_users), " and after cleaning: " , nrow(activity_cleaned)))
## [1] "Number of rows in Activity Table before cleaning: 940 and after cleaning: 940"
print(paste0("duplicate rows : " , nrow(activity_users) - nrow(activity_cleaned)))
## [1] "duplicate rows : 0"
print(paste0("Distinct Ids in Activity Table before cleaning: " , n_distinct(activity_users$Id), " and after cleaning: " , n_distinct(activity_cleaned$id)))
## [1] "Distinct Ids in Activity Table before cleaning: 33 and after cleaning: 33"
weight_cleaned <- weight_log_users %>%
clean_names() %>%
distinct() %>%
mutate(date_new = as.Date(mdy_hms(date))) %>%
mutate(id = as.character(id)) %>% # convert id to string
select(id, date_new, weight_kg, bmi)
print(paste0("Number of rows in Weight Table before cleaning: " , nrow(weight_log_users), " and after cleaning: " , nrow(weight_cleaned)))
## [1] "Number of rows in Weight Table before cleaning: 67 and after cleaning: 67"
print(paste0("duplicate rows : " , nrow(weight_log_users) - nrow(weight_cleaned)))
## [1] "duplicate rows : 0"
print(paste0("Distinct Ids in Activity Table before cleaning: " , n_distinct(weight_log_users$Id), " and after cleaning: " , n_distinct(weight_cleaned$id)))
## [1] "Distinct Ids in Activity Table before cleaning: 8 and after cleaning: 8"
sleep_cleaned <- sleep_users %>%
clean_names() %>%
distinct() %>%
mutate(id = as.character(id)) %>%
mutate(date_new = as.Date(mdy_hms(sleep_day))) %>%
select(id,date_new, total_minutes_asleep,total_time_in_bed)
print(paste0("Number of rows in Sleep Table before cleaning: " , nrow(sleep_users), " and after cleaning: " , nrow(sleep_cleaned)))
print(paste0("duplicate rows : " , nrow(sleep_users) - nrow(sleep_cleaned)))
print(paste0("Distinct Ids in Activity Table before cleaning: " , n_distinct(sleep_users$Id), " and after cleaning: " , n_distinct(sleep_cleaned$id)))
heart_rate_cleaned <- heart_rate %>%
clean_names() %>%
distinct() %>%
mutate(id = as.character(id))
heart_rate_cleaned <- separate(heart_rate_cleaned, time, c("date_new", "time"), sep = " ")
heart_rate_cleaned %>%
mutate(date_new = as.Date(mdy(date_new)))
print(paste0("Number of rows in heart rate Table before cleaning: " , nrow(heart_rate), " and after cleaning: " , nrow(heart_rate_cleaned)))
## [1] "Number of rows in heart rate Table before cleaning: 2483658 and after cleaning: 2483658"
print(paste0("duplicate rows : " , nrow(heart_rate) - nrow(heart_rate_cleaned)))
## [1] "duplicate rows : 0"
print(paste0("Distinct Ids in Activity Table before cleaning: " , n_distinct(heart_rate$Id), " and after cleaning: " , n_distinct(heart_rate_cleaned$id)))
## [1] "Distinct Ids in Activity Table before cleaning: 14 and after cleaning: 14"
use_frequency <- activity_cleaned %>%
count(id, sort = TRUE,name = "days")
Most people have used the tracker for 26 days or more
##bar plot of how are users divided
id_categories <- c(n_distinct(activity_cleaned$id),n_distinct(sleep_cleaned$id),n_distinct(heart_rate_cleaned$id), n_distinct(weight_cleaned$id))
barplot(id_categories,
main = "what features are users using the most",
xlab = "categories",
ylab = "Nmuber of Users",
names.arg = c("Activity user", "Sleep users","Heart Rate Users", "Weight Users"),
cex.names = 0.75,col = "Grey")
activity_cleaned_ids <- unique(activity_cleaned$id)
sleep_cleaned_id <- unique(sleep_cleaned$id)
weight_cleaned_id <- unique(weight_cleaned$id)
heart_rate_cleaned_id <- unique(heart_rate_cleaned$id)
library(ggvenn)
## Loading required package: grid
x = list(activity_cleaned_ids,sleep_cleaned_id,heart_rate_cleaned_id,weight_cleaned_id)
ggVennDiagram(x , category.names = c("Activity user", "Sleep users","Heart Rate Users", "Weight Users")) + scale_fill_gradient(low = "#F4FAFE", high = "#4981BF") + scale_x_continuous(expand = expansion(mult = .2))
#### Only 3 users out of the 33 users are using the full functionality
of the smart device which is around 9%. we have to keep in mind that the
sample size is too small to generalized results.
heart_rate_summary <- heart_rate_cleaned %>%
group_by(id,date_new) %>%
dplyr::summarize(avg_daily_heart_rate = mean(value)) %>%
mutate(date_new = as.Date(mdy(date_new)))
## `summarise()` has grouped output by 'id'. You can override using the `.groups`
## argument.
n_distinct(heart_rate_summary$id)
## [1] 14
heart_activity<- activity_cleaned[(activity_cleaned$id %in% heart_rate_summary$id),]
heart_activity_users <- merge(heart_activity, heart_rate_summary, by.x = c("id", "date_new"),by.y = c("id", "date_new"), all = TRUE)
sleep_activity_users<- activity_cleaned[(activity_cleaned$id %in% sleep_cleaned$id),]
sleep_activity_users<- merge(sleep_activity_users, sleep_cleaned, by.x=c("id", "date_new"), by.y=c("id", "date_new"),all = TRUE)
weight_activity_users<-activity_cleaned[(activity_cleaned$id %in% weight_cleaned$id),]
weight_activity_users<- merge(weight_activity_users, weight_cleaned, by.x=c("id", "date_new"), by.y=c("id", "date_new"),all = TRUE)
n_distinct(heart_activity_users$id)
## [1] 14
n_distinct(sleep_activity_users$id)
## [1] 24
n_distinct(weight_activity_users$id)
## [1] 8
##findig correlation by pearsons method
cor_activity = cor(activity_cleaned[, unlist(lapply(activity_cleaned, is.numeric))], use="pairwise.complete.obs")
corrplot(cor_activity, method="number", type = "lower",title = ("Activity Cor."),tl.cex = 0.9, tl.srt = 0)
cor_heart = cor(heart_activity_users[, unlist(lapply(heart_activity_users, is.numeric))], use="pairwise.complete.obs")
corrplot(cor_heart, method="number", type = "lower",title = "HR Activity cor.",tl.cex = 0.9, tl.srt = 0, )
cor_weight = cor(weight_activity_users[, unlist(lapply(weight_activity_users, is.numeric))], use="pairwise.complete.obs")
corrplot(cor_weight, method="number", type = "lower", title = "weight activity cor.",tl.cex = 0.9, tl.srt = 0, )
cor_sleep = cor(sleep_activity_users[, unlist(lapply(sleep_activity_users, is.numeric))], use="pairwise.complete.obs")
corrplot(cor_sleep, method="number", type = "lower", title = "sleep activity cor.",tl.cex = 0.9, tl.srt = 0)
- calroies are positevely correlated to total steps and active minutes
- average daily heart rate is positively related with sedentary mintues. which means less active people tend to have a higher heart rate.
- weight is positively related to sedentary minutes. which means less active people tend to be heavier
- bmi is negatively related to active minutes and positively to sendentary minutes. a higher bmi means a person is overweight/obese. so active people tend to have a lower bmi and sedentary people tend to have a higher bmi.
- Total sleep and bed time
all_functions_users <- activity_cleaned [((activity_cleaned$id %in% sleep_cleaned$id) & (activity_cleaned$id %in% weight_cleaned$id) & activity_cleaned$id %in% heart_rate_summary$id),]
n_distinct(all_functions_users$id)
## [1] 3
all_functions_users <- merge(all_functions_users, weight_cleaned, by.x=c("id", "date_new"), by.y=c("id", "date_new"),all.x = TRUE)
all_functions_users <- merge(all_functions_users, sleep_cleaned, by.x=c("id", "date_new"), by.y=c("id", "date_new"),all.x = TRUE)
all_functions_users <- merge(all_functions_users, heart_rate_summary, by.x=c("id", "date_new"), by.y=c("id", "date_new"),all.x = TRUE)
n_distinct(all_functions_users$id)
## [1] 3
cor_all = cor(all_functions_users[, unlist(lapply(all_functions_users, is.numeric))], use = "pairwise.complete.obs")
corrplot(cor_all, method="number", type = "lower", title = ("All Functions"),tl.cex = 0.9, tl.srt = 0)