Case Study Scenario

As a Junior Analyst working on the marketing analyst team at Bellabeat, I’ve been asked to analyze the smart device fitness data of users to gain insights into how they’re using their devices. The insights discovered will guide in developing a marketing strategy for the company. My task also includes focusing on one of Bellabeat’s products. Urška Sršen, cofounder and Chief Creative Officer of Bellabeat believes that analyzing the data will unlock new growth opportunities for the company.

Step 1: Setting up the Environment

install.packages("tidyverse")
## Installing package into '/cloud/lib/x86_64-pc-linux-gnu-library/4.4'
## (as 'lib' is unspecified)
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(ggplot2)
library(dplyr)
library(tidyr)
library(janitor)
## 
## Attaching package: 'janitor'
## 
## The following objects are masked from 'package:stats':
## 
##     chisq.test, fisher.test
install.packages("readr")
## Installing package into '/cloud/lib/x86_64-pc-linux-gnu-library/4.4'
## (as 'lib' is unspecified)
library(readr)

Step 2: Upload and Import Data, Create data frames for datasets

In the output pane, click the upload button. Browse and choose file. After selecting the file, click Import. Now run the code chunk below, read the file into a data frame:

Hourly_Intensities<- read_csv("hourlyIntensities_merged.csv")
## Rows: 24084 Columns: 4
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (1): ActivityHour
## dbl (3): Id, TotalIntensity, AverageIntensity
## 
## ℹ 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.
Sleep_Minutes<- read_csv("minuteSleep_merged[1].csv")
## Rows: 198559 Columns: 4
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (1): 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.
Daily_Activity<- read_csv("dailyActivity_Bella.csv")
## New names:
## Rows: 457 Columns: 20
## ── Column specification
## ──────────────────────────────────────────────────────── Delimiter: "," chr
## (2): Weight, ActivityDate dbl (16): Id, TotalSteps, TotalDistance,
## TrackerDistance, LoggedActivitiesDi... lgl (2): WeightLogged, ...18
## ℹ 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.
## • `` -> `...18`

Step 3: Looked at Sample of Data

head(Hourly_Intensities)
## # A tibble: 6 × 4
##           Id ActivityHour          TotalIntensity AverageIntensity
##        <dbl> <chr>                          <dbl>            <dbl>
## 1 1503960366 3/12/2016 12:00:00 AM              0                0
## 2 1503960366 3/12/2016 1:00:00 AM               0                0
## 3 1503960366 3/12/2016 2:00:00 AM               0                0
## 4 1503960366 3/12/2016 3:00:00 AM               0                0
## 5 1503960366 3/12/2016 4:00:00 AM               0                0
## 6 1503960366 3/12/2016 5:00:00 AM               0                0
str(Hourly_Intensities)
## spc_tbl_ [24,084 × 4] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ Id              : num [1:24084] 1.5e+09 1.5e+09 1.5e+09 1.5e+09 1.5e+09 ...
##  $ ActivityHour    : chr [1:24084] "3/12/2016 12:00:00 AM" "3/12/2016 1:00:00 AM" "3/12/2016 2:00:00 AM" "3/12/2016 3:00:00 AM" ...
##  $ TotalIntensity  : num [1:24084] 0 0 0 0 0 0 0 0 0 1 ...
##  $ AverageIntensity: num [1:24084] 0 0 0 0 0 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   Id = col_double(),
##   ..   ActivityHour = col_character(),
##   ..   TotalIntensity = col_double(),
##   ..   AverageIntensity = col_double()
##   .. )
##  - attr(*, "problems")=<externalptr>
colnames(Hourly_Intensities)
## [1] "Id"               "ActivityHour"     "TotalIntensity"   "AverageIntensity"
head(Sleep_Minutes)
## # A tibble: 6 × 4
##           Id date                 value       logId
##        <dbl> <chr>                <dbl>       <dbl>
## 1 1503960366 3/13/2016 2:39:30 AM     1 11114919637
## 2 1503960366 3/13/2016 2:40:30 AM     1 11114919637
## 3 1503960366 3/13/2016 2:41:30 AM     1 11114919637
## 4 1503960366 3/13/2016 2:42:30 AM     1 11114919637
## 5 1503960366 3/13/2016 2:43:30 AM     1 11114919637
## 6 1503960366 3/13/2016 2:44:30 AM     1 11114919637
str(Sleep_Minutes)
## spc_tbl_ [198,559 × 4] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ Id   : num [1:198559] 1.5e+09 1.5e+09 1.5e+09 1.5e+09 1.5e+09 ...
##  $ date : chr [1:198559] "3/13/2016 2:39:30 AM" "3/13/2016 2:40:30 AM" "3/13/2016 2:41:30 AM" "3/13/2016 2:42:30 AM" ...
##  $ value: num [1:198559] 1 1 1 1 1 1 2 2 1 1 ...
##  $ logId: num [1:198559] 1.11e+10 1.11e+10 1.11e+10 1.11e+10 1.11e+10 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   Id = col_double(),
##   ..   date = col_character(),
##   ..   value = col_double(),
##   ..   logId = col_double()
##   .. )
##  - attr(*, "problems")=<externalptr>
colnames(Sleep_Minutes)
## [1] "Id"    "date"  "value" "logId"
head(Daily_Activity)
## # A tibble: 6 × 20
##           Id Weight WeightLogged ActivityDate TotalSteps TotalDistance
##        <dbl> <chr>  <lgl>        <chr>             <dbl>         <dbl>
## 1 1503960366 53.30  TRUE         3/25/2016         11004          7.11
## 2 1503960366 53.30  TRUE         3/26/2016         17609         11.6 
## 3 1503960366 53.30  TRUE         3/27/2016         12736          8.53
## 4 1503960366 53.30  TRUE         3/28/2016         13231          8.93
## 5 1503960366 53.30  TRUE         3/29/2016         12041          7.85
## 6 1503960366 53.30  TRUE         3/30/2016         10970          7.16
## # ℹ 14 more variables: TrackerDistance <dbl>, LoggedActivitiesDistance <dbl>,
## #   VeryActiveDistance <dbl>, ModeratelyActiveDistance <dbl>,
## #   LightActiveDistance <dbl>, SedentaryActiveDistance <dbl>,
## #   VeryActiveMinutes <dbl>, FairlyActiveMinutes <dbl>,
## #   LightlyActiveMinutes <dbl>, SedentaryMinutes <dbl>, Calories <dbl>,
## #   ...18 <lgl>, ID2 <dbl>, WeightKg <dbl>
str(Daily_Activity)
## spc_tbl_ [457 × 20] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ Id                      : num [1:457] 1.5e+09 1.5e+09 1.5e+09 1.5e+09 1.5e+09 ...
##  $ Weight                  : chr [1:457] "53.30" "53.30" "53.30" "53.30" ...
##  $ WeightLogged            : logi [1:457] TRUE TRUE TRUE TRUE TRUE TRUE ...
##  $ ActivityDate            : chr [1:457] "3/25/2016" "3/26/2016" "3/27/2016" "3/28/2016" ...
##  $ TotalSteps              : num [1:457] 11004 17609 12736 13231 12041 ...
##  $ TotalDistance           : num [1:457] 7.11 11.55 8.53 8.93 7.85 ...
##  $ TrackerDistance         : num [1:457] 7.11 11.55 8.53 8.93 7.85 ...
##  $ LoggedActivitiesDistance: num [1:457] 0 0 0 0 0 0 0 0 0 0 ...
##  $ VeryActiveDistance      : num [1:457] 2.57 6.92 4.66 3.19 2.16 ...
##  $ ModeratelyActiveDistance: num [1:457] 0.46 0.73 0.16 0.79 1.09 ...
##  $ LightActiveDistance     : num [1:457] 4.07 3.91 3.71 4.95 4.61 ...
##  $ SedentaryActiveDistance : num [1:457] 0 0 0 0 0 0 0 0 0 0 ...
##  $ VeryActiveMinutes       : num [1:457] 33 89 56 39 28 30 33 47 40 15 ...
##  $ FairlyActiveMinutes     : num [1:457] 12 17 5 20 28 13 12 21 11 30 ...
##  $ LightlyActiveMinutes    : num [1:457] 205 274 268 224 243 223 239 200 244 314 ...
##  $ SedentaryMinutes        : num [1:457] 804 588 605 1080 763 ...
##  $ Calories                : num [1:457] 1819 2154 1944 1932 1886 ...
##  $ ...18                   : logi [1:457] NA NA NA NA NA NA ...
##  $ ID2                     : num [1:457] 1.50e+09 1.93e+09 2.35e+09 2.87e+09 2.87e+09 ...
##  $ WeightKg                : num [1:457] 53.3 129.6 63.4 56.7 57.2 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   Id = col_double(),
##   ..   Weight = col_character(),
##   ..   WeightLogged = col_logical(),
##   ..   ActivityDate = col_character(),
##   ..   TotalSteps = col_double(),
##   ..   TotalDistance = col_double(),
##   ..   TrackerDistance = col_double(),
##   ..   LoggedActivitiesDistance = col_double(),
##   ..   VeryActiveDistance = col_double(),
##   ..   ModeratelyActiveDistance = col_double(),
##   ..   LightActiveDistance = col_double(),
##   ..   SedentaryActiveDistance = col_double(),
##   ..   VeryActiveMinutes = col_double(),
##   ..   FairlyActiveMinutes = col_double(),
##   ..   LightlyActiveMinutes = col_double(),
##   ..   SedentaryMinutes = col_double(),
##   ..   Calories = col_double(),
##   ..   ...18 = col_logical(),
##   ..   ID2 = col_double(),
##   ..   WeightKg = col_double()
##   .. )
##  - attr(*, "problems")=<externalptr>
colnames(Daily_Activity)
##  [1] "Id"                       "Weight"                  
##  [3] "WeightLogged"             "ActivityDate"            
##  [5] "TotalSteps"               "TotalDistance"           
##  [7] "TrackerDistance"          "LoggedActivitiesDistance"
##  [9] "VeryActiveDistance"       "ModeratelyActiveDistance"
## [11] "LightActiveDistance"      "SedentaryActiveDistance" 
## [13] "VeryActiveMinutes"        "FairlyActiveMinutes"     
## [15] "LightlyActiveMinutes"     "SedentaryMinutes"        
## [17] "Calories"                 "...18"                   
## [19] "ID2"                      "WeightKg"

Step 4: I wanted to know how many distinct userids there were in the datasets.

n_distinct(Daily_Activity$Id)
## [1] 35
n_distinct(Sleep_Minutes$Id)
## [1] 23
n_distinct(Hourly_Intensities$Id)
## [1] 34
n_distinct(Daily_Activity$WeightLogged)
## [1] 2

There were 35 distinct users who submitted information for their daily activities. Only 12 of the users submitted weight tracking information, and 23 users submitted their sleep data. The sleep data for the period 3.12.16-4.11.16 contained limited information regarding the sleep habits of the users, so It was left out of analysis.6

Step 5: I wanted to perform a statisitcal analysis of the datasets

Daily_Activity %>% 
  select(TotalSteps, TotalDistance, Calories, SedentaryMinutes, VeryActiveMinutes, LightlyActiveMinutes, VeryActiveMinutes)%>%
  summary()
##    TotalSteps    TotalDistance       Calories    SedentaryMinutes
##  Min.   :    0   Min.   : 0.000   Min.   :   0   Min.   :  32.0  
##  1st Qu.: 1988   1st Qu.: 1.410   1st Qu.:1776   1st Qu.: 728.0  
##  Median : 5986   Median : 4.090   Median :2062   Median :1057.0  
##  Mean   : 6547   Mean   : 4.664   Mean   :2189   Mean   : 995.3  
##  3rd Qu.:10198   3rd Qu.: 7.160   3rd Qu.:2667   3rd Qu.:1285.0  
##  Max.   :28497   Max.   :27.530   Max.   :4562   Max.   :1440.0  
##  VeryActiveMinutes LightlyActiveMinutes
##  Min.   :  0.00    Min.   :  0.0       
##  1st Qu.:  0.00    1st Qu.: 64.0       
##  Median :  0.00    Median :181.0       
##  Mean   : 16.62    Mean   :170.1       
##  3rd Qu.: 25.00    3rd Qu.:257.0       
##  Max.   :202.00    Max.   :720.0

After reviewing the summary, I also wanted to know which UserId had the Max total steps. I wanted this information to test my hypothesis.

max_Steps_user<-data.frame(which.max(Daily_Activity$TotalSteps))
print(max_Steps_user)
##   which.max.Daily_Activity.TotalSteps.
## 1                                  455
Hourly_Intensities %>%
  select(ActivityHour, TotalIntensity,AverageIntensity)%>%
  summary()
##  ActivityHour       TotalIntensity   AverageIntensity 
##  Length:24084       Min.   :  0.00   Min.   :0.00000  
##  Class :character   1st Qu.:  0.00   1st Qu.:0.00000  
##  Mode  :character   Median :  1.00   Median :0.01667  
##                     Mean   : 10.83   Mean   :0.18044  
##                     3rd Qu.: 14.00   3rd Qu.:0.23333  
##                     Max.   :180.00   Max.   :3.00000

Step 6: Create Vectors and Data Frames for Analysis

Distinct_Id2<- c(1503960366,1624580081,1644430081,1844505072,1927972279,2022484408,2026352035,2320127002,2347167796,2873212765,2891001357,3372868164,3977333714,4020332650,
4057192912,4319703577,4388161847,4445114986,4558609924,4702921684,5553957443,5577150313,6117666160,6290855005,6391747486,6775888955,6962181067,7007744171,7086361926,8053475328,
8253242879,8378563200,8583815059,8792009665,8877689391)
Total_Calories2<- c(34128,25705,29164,19391,27048,29704,16266,18385,30320,20349,18187,18603,16777,98412,60913,23931,14442,31617,21962,42322,21630,36303,20993,
21656,15868,24523,29249,31525,26124,31825,17556,40274,19130,24884,41414)
Total_Steps2<- c(221170,80299,92748,43687,26170,146099,40713,37661,147001,79639,6189,61275,103967,184851,60391,93847,0,64396,69423,119151,100257,94690,82486,16181,12032,
50031,176956,147124,73247,163288,28679,97623,24364,37139,209005)
Calories_Burned_From_Activity<-data.frame(Distinct_Id2,Total_Calories2,Total_Steps2)

As I began to explore the data, I hypothesized that the users who burned the most total calories were also one of the 12 users who also logged their weight using their devices. Right away, I wanted to look more into what drives customers to log their weight, and how we can motivate users to track their weights more consistently by enhancing our current product offerings. In addition, the data shows that most users recorded the most amount of steps and burned the most calories between the hours of 12pm-4pm, and I wanted to create a visual to highlight the positive correlation between calories burned and steps taken. Furthermore to test my hypothesis I utilized the print function, and it was determined that User 8877689391 recorded the Max number of steps, and also tracked their weight.
## Step 7: Data Visualizations

ggplot(data=Calories_Burned_From_Activity)+geom_smooth(mapping=aes(Total_Steps2,y=Total_Calories2))+ labs(title = "Calories Burned vs. Steps" )
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'

ggsave('Calories Burned vs. Steps.pdf')
## Saving 7 x 5 in image
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'