Hi, this is my BellaBeat case study. Here, we will process, analyze and share data collected from a wareable smart device in order to gain insight into how consumers are using their smart devices. Our client is Bellabeat, a smart device company based in San Francisco. Throughout this study, we will follow the data analysis process to answer key business questions and develop actionable insights.
Bellabeats’s goal: Become a larger player in the global smart device market.
Products:
App: track activity, sleep, stress, menstrual cycle, and mindfulness habits. Wearable Device: connects to the app to track activity, sleep, and stress. Watch: connects to the app to track activity, sleep, and stress. Water Bottle: connects to the app to track daily water intake. Subscription membership: personalized guidance on nutrition, activity, sleep, health, beauty, and mindfulness based on their lifestyle and goals.
We will deliver a clear statement of the business task. A description of all data sources used. Documentation of any cleaning or manipulation of data. A summary of our analysis. Supporting visualizations and key findings. Our top high-level insights based on our analysis.
BellaBeat is a successful health-tech manufacturer of health-focused products for women that would like to see their company grow. Based on review of consumer data they would like a high-level recommendations for how trends can inform Bella beat marketing strategy.
Analyze provided smart device usage data to gain insight into how consumers use non-Bellabeat smart devices. Select one Bellabeat product to apply these insights to in your presentation.
These questions will guide your analysis:
What are some trends in smart device usage? How could these trends apply to Bellabeat customers? *How could these trends help influence Bellabeat’s marketing strategy?
I will produce a report with the following 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 My top high-level content recommendations based on your analysis
This Kaggle data set contains personal fitness trackers from thirty-three Fitbit users. Thirty-three eligible Fitbit users consented to the submission of personal tracker data, including minute-level output for physical activity, heart rate, and sleep monitoring. It includes information about daily activity, steps, and heart rate that can be used to explore users’ habits.
Our goal is to essentially give broad strokes data about the Bellabeats users. We want to mainly focus on daily data and specifically the dailyActivity_merged file. The dailyActivity_merged has all the “daily” sheet titled columns already merged into it except sleep.
Upload Packages
.packages = c("tidyverse","lubridate","ggplot2","ggpubr","tidyr","janitor","readr","here", "dplyr","skimr")
.inst <- .packages %in% installed.packages()
if(length(.packages[!.inst]) > 0) install.packages(.packages[!.inst])
lapply(.packages, require, character.only=TRUE)
## Loading required package: 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
## Loading required package: ggpubr
##
## Loading required package: janitor
##
##
## Attaching package: 'janitor'
##
##
## The following objects are masked from 'package:stats':
##
## chisq.test, fisher.test
##
##
## Loading required package: here
##
## here() starts at /cloud/project
##
## Loading required package: skimr
## [[1]]
## [1] TRUE
##
## [[2]]
## [1] TRUE
##
## [[3]]
## [1] TRUE
##
## [[4]]
## [1] TRUE
##
## [[5]]
## [1] TRUE
##
## [[6]]
## [1] TRUE
##
## [[7]]
## [1] TRUE
##
## [[8]]
## [1] TRUE
##
## [[9]]
## [1] TRUE
##
## [[10]]
## [1] TRUE
Read data into dataframes
daily_activity <- read_csv("dailyActivity_merged.csv")
## Rows: 940 Columns: 15
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (1): ActivityDate
## dbl (14): Id, TotalSteps, TotalDistance, TrackerDistance, LoggedActivitiesDi...
##
## ℹ 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.
daily_sleep <- read_csv("sleepDay_merged.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.
n_distinct(daily_activity$Id)
## [1] 33
n_distinct(daily_sleep$Id)
## [1] 24
head(daily_activity)
## # 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: LoggedActivitiesDistance <dbl>,
## # VeryActiveDistance <dbl>, ModeratelyActiveDistance <dbl>,
## # LightActiveDistance <dbl>, SedentaryActiveDistance <dbl>,
## # VeryActiveMinutes <dbl>, FairlyActiveMinutes <dbl>,
## # LightlyActiveMinutes <dbl>, SedentaryMinutes <dbl>, Calories <dbl>
head(daily_sleep)
## # 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
names(daily_activity)
## [1] "Id" "ActivityDate"
## [3] "TotalSteps" "TotalDistance"
## [5] "TrackerDistance" "LoggedActivitiesDistance"
## [7] "VeryActiveDistance" "ModeratelyActiveDistance"
## [9] "LightActiveDistance" "SedentaryActiveDistance"
## [11] "VeryActiveMinutes" "FairlyActiveMinutes"
## [13] "LightlyActiveMinutes" "SedentaryMinutes"
## [15] "Calories"
names(daily_sleep)
## [1] "Id" "SleepDay" "TotalSleepRecords"
## [4] "TotalMinutesAsleep" "TotalTimeInBed"
Clean duplicates, null data
sum(duplicated(daily_activity))
## [1] 0
sum(duplicated(daily_sleep))
## [1] 3
there are 3 duplicates in sleep lets remove them
duplicates <- daily_sleep[duplicated(daily_sleep) | duplicated(daily_sleep, fromLast = TRUE), ]
daily_sleep <- daily_sleep[!duplicated(daily_sleep), ]
sum(duplicated(daily_sleep))
## [1] 0
any(is.na(daily_activity))
## [1] FALSE
any(is.na(daily_sleep))
## [1] FALSE
There are no missing values
reminder we are limiting our analysis to Sleep miniutes, Activity (VeryActiveMiniutes,FairlyActiveMiniutes,LightlyActiveMiniutes,TotalActiveMiniutes) *Calories per Day
daily_activity%>%
select(VeryActiveMinutes, FairlyActiveMinutes, LightlyActiveMinutes) %>%
summary()
## VeryActiveMinutes FairlyActiveMinutes LightlyActiveMinutes
## Min. : 0.00 Min. : 0.00 Min. : 0.0
## 1st Qu.: 0.00 1st Qu.: 0.00 1st Qu.:127.0
## Median : 4.00 Median : 6.00 Median :199.0
## Mean : 21.16 Mean : 13.56 Mean :192.8
## 3rd Qu.: 32.00 3rd Qu.: 19.00 3rd Qu.:264.0
## Max. :210.00 Max. :143.00 Max. :518.0
daily_activity %>%
select(Calories) %>%
summary()
## Calories
## Min. : 0
## 1st Qu.:1828
## Median :2134
## Mean :2304
## 3rd Qu.:2793
## Max. :4900
daily_sleep %>%
select(TotalMinutesAsleep) %>%
summary()
## TotalMinutesAsleep
## Min. : 58.0
## 1st Qu.:361.0
## Median :432.5
## Mean :419.2
## 3rd Qu.:490.0
## Max. :796.0
create a new variable TotalActiveMinutes
daily_activity <- daily_activity %>%
mutate(TotalActiveMinutes = VeryActiveMinutes + FairlyActiveMinutes + LightlyActiveMinutes)
I am going to want to merge data from Sleep and Daily Activity First I will reformat date columns in each to match
Rename SleepDay column in daily_sleep to date
daily_sleep <- daily_sleep %>%
rename(date = SleepDay)
daily_activity <- daily_activity %>%
rename(date = ActivityDate)
Convert date columns to the desired format MM/DD/YYYY First, remove unneeded time info from date in sleep
daily_sleep$date <- sub(" .*", "", daily_sleep$date)
daily_sleep$date <- as.Date(daily_sleep$date, format = "%m/%d/%Y")
daily_activity$date <- as.Date(daily_activity$date, format = "%m/%d/%Y")
Activity vs Calories
ggplot(daily_activity, aes(x = TotalActiveMinutes, y = Calories)) +
geom_point()
Activity vs Sleep
# Merge data based on Id and date columns
merged_tactive_sleep <- merge(daily_activity[, c("Id", "date", "TotalActiveMinutes")],
daily_sleep[, c("Id", "TotalMinutesAsleep", "date")],
by = c("Id", "date"), all = TRUE)
ggplot(merged_tactive_sleep, aes(x = TotalActiveMinutes, y = TotalMinutesAsleep)) +
geom_point()
## Warning: Removed 530 rows containing missing values or values outside the scale range
## (`geom_point()`).
# Merge data based on Id and date columns
merged_calories_sleep <- merge(daily_activity[, c("Id", "date", "Calories")],
daily_sleep[, c("Id", "TotalMinutesAsleep", "date")],
by = c("Id", "date"), all = TRUE)
ggplot(merged_calories_sleep, aes(x = Calories, y = TotalMinutesAsleep)) +
geom_point()
## Warning: Removed 530 rows containing missing values or values outside the scale range
## (`geom_point()`).
There appears to be a relationship between Calories and Activity Minutes We can investigate further by looking at different levels of activity vs calories
There is a positive relationship between activity and calories that is most pronounced during very active times. And is more pronounced after approximately 30 minutes of very active time.
This strong relationship suggests that customers could be encouraged to increasing tracking of intensity of activity and calories. Tracking calories could be made easier by encorporating the latest software that calculates calories based on a photo taken of the food.
Next steps. Conclusions could be strengthened by review of actual data from BellaBeats over a longer time period of time.