Business Task

This project has been initiated by the CEO and Co-Founder of the company Bellabeat, she wants to know how can the trends in smart devices inform Bellabeat marketing strategy. I was assigned to this project, being a junior data analyst who joined the company six months ago. It is going to be a great opportunity for me to apply my knowledge in the data analytics field to come up with useful insights and conclusions. The marketing department are going to make strategic decisions based on the insights gained from this analysis in terms of customers’ behaviors.

Stakeholders:

My main stakeholders are: - The CEO and Co-Founder Sršen. - The CO of the marketing department. ### Business Task: Discover trends in how people are using smart devices and make recommandations on for how these trends can inform Bellabeat marketing strategy. # Data Collection

The dataset that we will be using in this analysis is an open source dataset taken from the well known platform KAGGLE, it gives a detailed recording of different daily activities of a certain num # Data Processing Documentation of any cleaning or manipulation of data ## Set up the R 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

Import Data

We have decided to use R programming language for this project because the dataset is too large for a spearsheet, the R give us the possibility to clean,transform and analyse data but also and more importantly allows great ways of visualization. Before we can upload our data, let’s first check the default path to our directory using the following function:

getwd()
## [1] "/cloud/project"

Now, we can uppload our files using thefunction read.csv, included in the package READR that has been installed with TIDYVERSE. Additionaly, I used to the function na.omit to erase null values from the rows in the different data frame. Later on, I am going to show you how does each data frame look like using different functions.

heartrate_seconds <- na.omit(read.csv("heartrate_seconds_merged.csv"))
#Hourly recordings
hourly_calories<- na.omit(read.csv("hourlyCalories_merged.csv"))
hourly_intensities <- na.omit(read.csv("hourlyIntensities_merged.csv"))
hourly_steps <- na.omit(read.csv("hourlySteps_merged.csv"))
#minute recordings
minute_calories <- na.omit(read.csv("minuteCaloriesNarrow_merged.csv"))
minute_intensities <- na.omit(read.csv("minuteIntensitiesNarrow_merged.csv"))
minute_mets_narrow <- na.omit(read.csv("minuteMETsNarrow_merged.csv"))
minute_sleep <- na.omit(read.csv("minuteSleep_merged.csv"))
minute_steps_narrow <- na.omit(read.csv("minuteStepsNarrow_merged.csv"))
#Weight Log Info
weight_log_inf<- na.omit(read.csv("weightLogInfo_merged.csv"))

let’s as explore a little bit our dataset by showing first rows, let’s look at the columns names, number of rows,type of data and other useful informations. We will be using two functions head and gimpse, of course there are many others but let us use only these two for the moment :

head(heartrate_seconds)
##           Id                Time Value
## 1 2022484408 4/1/2016 7:54:00 AM    93
## 2 2022484408 4/1/2016 7:54:05 AM    91
## 3 2022484408 4/1/2016 7:54:10 AM    96
## 4 2022484408 4/1/2016 7:54:15 AM    98
## 5 2022484408 4/1/2016 7:54:20 AM   100
## 6 2022484408 4/1/2016 7:54:25 AM   101
head(hourly_calories)
##           Id          ActivityHour Calories
## 1 1503960366 3/12/2016 12:00:00 AM       48
## 2 1503960366  3/12/2016 1:00:00 AM       48
## 3 1503960366  3/12/2016 2:00:00 AM       48
## 4 1503960366  3/12/2016 3:00:00 AM       48
## 5 1503960366  3/12/2016 4:00:00 AM       48
## 6 1503960366  3/12/2016 5:00:00 AM       48
head(hourly_intensities)
##           Id          ActivityHour TotalIntensity AverageIntensity
## 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
head(hourly_steps)
##           Id          ActivityHour StepTotal
## 1 1503960366 3/12/2016 12:00:00 AM         0
## 2 1503960366  3/12/2016 1:00:00 AM         0
## 3 1503960366  3/12/2016 2:00:00 AM         0
## 4 1503960366  3/12/2016 3:00:00 AM         0
## 5 1503960366  3/12/2016 4:00:00 AM         0
## 6 1503960366  3/12/2016 5:00:00 AM         0
head(minute_calories)
##           Id        ActivityMinute Calories
## 1 1503960366 3/12/2016 12:00:00 AM   0.7973
## 2 1503960366 3/12/2016 12:01:00 AM   0.7973
## 3 1503960366 3/12/2016 12:02:00 AM   0.7973
## 4 1503960366 3/12/2016 12:03:00 AM   0.7973
## 5 1503960366 3/12/2016 12:04:00 AM   0.7973
## 6 1503960366 3/12/2016 12:05:00 AM   0.7973
head(minute_intensities)
##           Id        ActivityMinute Intensity
## 1 1503960366 3/12/2016 12:00:00 AM         0
## 2 1503960366 3/12/2016 12:01:00 AM         0
## 3 1503960366 3/12/2016 12:02:00 AM         0
## 4 1503960366 3/12/2016 12:03:00 AM         0
## 5 1503960366 3/12/2016 12:04:00 AM         0
## 6 1503960366 3/12/2016 12:05:00 AM         0
head(minute_mets_narrow)
##           Id        ActivityMinute METs
## 1 1503960366 3/12/2016 12:00:00 AM   10
## 2 1503960366 3/12/2016 12:01:00 AM   10
## 3 1503960366 3/12/2016 12:02:00 AM   10
## 4 1503960366 3/12/2016 12:03:00 AM   10
## 5 1503960366 3/12/2016 12:04:00 AM   10
## 6 1503960366 3/12/2016 12:05:00 AM   10
head(minute_sleep)
##           Id                 date value       logId
## 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
head(minute_steps_narrow)
##           Id        ActivityMinute Steps
## 1 1503960366 3/12/2016 12:00:00 AM     0
## 2 1503960366 3/12/2016 12:01:00 AM     0
## 3 1503960366 3/12/2016 12:02:00 AM     0
## 4 1503960366 3/12/2016 12:03:00 AM     0
## 5 1503960366 3/12/2016 12:04:00 AM     0
## 6 1503960366 3/12/2016 12:05:00 AM     0
head(weight_log_inf)
##           Id                 Date WeightKg WeightPounds Fat   BMI
## 1 1503960366 4/5/2016 11:59:59 PM     53.3     117.5064  22 22.97
## 3 2347167796 4/3/2016 11:59:59 PM     63.4     139.7731  10 24.77
##   IsManualReport        LogId
## 1           True 1.459901e+12
## 3           True 1.459728e+12
glimpse(heartrate_seconds)
## Rows: 1,154,681
## Columns: 3
## $ Id    <dbl> 2022484408, 2022484408, 2022484408, 2022484408, 2022484408, 2022…
## $ Time  <chr> "4/1/2016 7:54:00 AM", "4/1/2016 7:54:05 AM", "4/1/2016 7:54:10 …
## $ Value <int> 93, 91, 96, 98, 100, 101, 104, 105, 102, 106, 109, 112, 111, 109…
glimpse(hourly_calories)
## Rows: 24,084
## Columns: 3
## $ Id           <dbl> 1503960366, 1503960366, 1503960366, 1503960366, 150396036…
## $ ActivityHour <chr> "3/12/2016 12:00:00 AM", "3/12/2016 1:00:00 AM", "3/12/20…
## $ Calories     <int> 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 89, 134, 130, 81,…
glimpse(hourly_intensities)
## Rows: 24,084
## Columns: 4
## $ Id               <dbl> 1503960366, 1503960366, 1503960366, 1503960366, 15039…
## $ ActivityHour     <chr> "3/12/2016 12:00:00 AM", "3/12/2016 1:00:00 AM", "3/1…
## $ TotalIntensity   <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 26, 49, 47, 20, 121, 12…
## $ AverageIntensity <dbl> 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.0…
glimpse(hourly_steps)
## Rows: 24,084
## Columns: 3
## $ Id           <dbl> 1503960366, 1503960366, 1503960366, 1503960366, 150396036…
## $ ActivityHour <chr> "3/12/2016 12:00:00 AM", "3/12/2016 1:00:00 AM", "3/12/20…
## $ StepTotal    <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 551, 1764, 1259, 253, 4470,…
glimpse(minute_calories)
## Rows: 1,445,040
## Columns: 3
## $ Id             <dbl> 1503960366, 1503960366, 1503960366, 1503960366, 1503960…
## $ ActivityMinute <chr> "3/12/2016 12:00:00 AM", "3/12/2016 12:01:00 AM", "3/12…
## $ Calories       <dbl> 0.7973, 0.7973, 0.7973, 0.7973, 0.7973, 0.7973, 0.7973,…
glimpse(minute_intensities)
## Rows: 1,445,040
## Columns: 3
## $ Id             <dbl> 1503960366, 1503960366, 1503960366, 1503960366, 1503960…
## $ ActivityMinute <chr> "3/12/2016 12:00:00 AM", "3/12/2016 12:01:00 AM", "3/12…
## $ Intensity      <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
glimpse(minute_mets_narrow)
## Rows: 1,445,040
## Columns: 3
## $ Id             <dbl> 1503960366, 1503960366, 1503960366, 1503960366, 1503960…
## $ ActivityMinute <chr> "3/12/2016 12:00:00 AM", "3/12/2016 12:01:00 AM", "3/12…
## $ METs           <int> 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,…
glimpse(minute_sleep)
## Rows: 198,559
## Columns: 4
## $ Id    <dbl> 1503960366, 1503960366, 1503960366, 1503960366, 1503960366, 1503…
## $ date  <chr> "3/13/2016 2:39:30 AM", "3/13/2016 2:40:30 AM", "3/13/2016 2:41:…
## $ value <int> 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
## $ logId <dbl> 11114919637, 11114919637, 11114919637, 11114919637, 11114919637,…
glimpse(minute_steps_narrow)
## Rows: 1,445,040
## Columns: 3
## $ Id             <dbl> 1503960366, 1503960366, 1503960366, 1503960366, 1503960…
## $ ActivityMinute <chr> "3/12/2016 12:00:00 AM", "3/12/2016 12:01:00 AM", "3/12…
## $ Steps          <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
glimpse(weight_log_inf)
## Rows: 2
## Columns: 8
## $ Id             <dbl> 1503960366, 2347167796
## $ Date           <chr> "4/5/2016 11:59:59 PM", "4/3/2016 11:59:59 PM"
## $ WeightKg       <dbl> 53.3, 63.4
## $ WeightPounds   <dbl> 117.5064, 139.7731
## $ Fat            <int> 22, 10
## $ BMI            <dbl> 22.97, 24.77
## $ IsManualReport <chr> "True", "True"
## $ LogId          <dbl> 1.459901e+12, 1.459728e+12

We will now merge the hourly records using the function merge

#First, we will install and load the package *janitor*
install.packages("janitor")
## Installing package into '/cloud/lib/x86_64-pc-linux-gnu-library/4.4'
## (as 'lib' is unspecified)
library(janitor)
## 
## Attaching package: 'janitor'
## The following objects are masked from 'package:stats':
## 
##     chisq.test, fisher.test
#Second, let's call the new data set hourly_record, the primary key is "Id":
hourly_record<- merge(hourly_calories,hourly_steps,by=c("Id","ActivityHour"))
head(hourly_record)
##           Id          ActivityHour Calories StepTotal
## 1 1503960366  3/12/2016 1:00:00 AM       48         0
## 2 1503960366  3/12/2016 1:00:00 PM       81       253
## 3 1503960366 3/12/2016 10:00:00 AM       89       551
## 4 1503960366 3/12/2016 10:00:00 PM      123      1132
## 5 1503960366 3/12/2016 11:00:00 AM      134      1764
## 6 1503960366 3/12/2016 11:00:00 PM      111       918

We will now add the information about intensities to the merged table that we just created:

install.packages("janitor")
## Installing package into '/cloud/lib/x86_64-pc-linux-gnu-library/4.4'
## (as 'lib' is unspecified)
library(janitor)
hourly_record<- merge(hourly_record,hourly_intensities,by=c("Id","ActivityHour"))
head(hourly_record)
##           Id          ActivityHour Calories StepTotal TotalIntensity
## 1 1503960366  3/12/2016 1:00:00 AM       48         0              0
## 2 1503960366  3/12/2016 1:00:00 PM       81       253             20
## 3 1503960366 3/12/2016 10:00:00 AM       89       551             26
## 4 1503960366 3/12/2016 10:00:00 PM      123      1132             41
## 5 1503960366 3/12/2016 11:00:00 AM      134      1764             49
## 6 1503960366 3/12/2016 11:00:00 PM      111       918             35
##   AverageIntensity
## 1         0.000000
## 2         0.333333
## 3         0.433333
## 4         0.683333
## 5         0.816667
## 6         0.583333

To be able to add the information about minute_sleep to this merged table, we need to summarise it, let’s do it using this code and the result is going to be named daily_minute_sleep :

daily_minute_sleep<-minute_sleep %>% 
  group_by(Id) %>% 
  summarise("sum_sleep_minute"=sum(value))
head(daily_minute_sleep)
## # A tibble: 6 × 2
##           Id sum_sleep_minute
##        <dbl>            <int>
## 1 1503960366            10459
## 2 1644430081             2520
## 3 1844505072             2546
## 4 1927972279            12102
## 5 2022484408              153
## 6 2026352035            18848

We will merge the obtained table with the hourly_record created previously. The result is going to be our daily_records_sum

Daily_records_sum<- merge(daily_minute_sleep, 
                          hourly_record %>% 
                          group_by(Id) %>%
                          summarise(daily_avg_calories=round(mean(Calories),digits=2),
                          daily_avg_steps=round(mean(StepTotal),digits=2),
                          daily_avg_intensities=round(mean(TotalIntensity),digits=2)),
                          by="Id") 
head(Daily_records_sum)
##           Id sum_sleep_minute daily_avg_calories daily_avg_steps
## 1 1503960366            10459              81.08          547.71
## 2 1644430081             2520             126.72          334.79
## 3 1844505072             2546              62.71           69.61
## 4 1927972279            12102             109.39          227.33
## 5 2022484408              153             108.86          530.94
## 6 2026352035            18848              61.66          187.95
##   daily_avg_intensities
## 1                 17.24
## 2                 14.83
## 3                  3.11
## 4                  9.02
## 5                 18.52
## 6                  8.84

Same thing with heart rate values, let’s summarize it using the average per day, the result is going to be named daily_minute_sleep :

daily_heartrate_avg<- heartrate_seconds %>% 
  group_by(Id) %>% 
  summarise(avg_heartrate=mean(Value))
head(daily_heartrate_avg)
## # A tibble: 6 × 2
##           Id avg_heartrate
##        <dbl>         <dbl>
## 1 2022484408          81.7
## 2 2026352035          65.8
## 3 2347167796          76.1
## 4 4020332650          81.9
## 5 4558609924          79.6
## 6 5553957443          69.4

Finally, we will merge the obtained table(daily_heartrate_avg) with the daily_records_sum created previously. The result is going to be our daily_records that give us all information that we need for our analysis, we will show the result using the function “head”.

Daily_records<- merge(daily_heartrate_avg, Daily_records_sum,by="Id") 
#To show you how does the result look like, we will use the function head():
head(Daily_records)
##           Id avg_heartrate sum_sleep_minute daily_avg_calories daily_avg_steps
## 1 2022484408      81.68851              153             108.86          530.94
## 2 2026352035      65.77904            18848              61.66          187.95
## 3 2347167796      76.06874            14940              89.20          434.17
## 4 4020332650      81.90180             6101             112.52          155.81
## 5 4558609924      79.55230              666              74.88          191.29
## 6 5553957443      69.41880            16231              75.23          290.44
##   daily_avg_intensities
## 1                 18.52
## 2                  8.84
## 3                 14.97
## 4                  6.74
## 5                  9.03
## 6                 10.33

Clean Data

The data is cleaned up since we used the function na.omit() at the beggining when we upploaded our data, the columns that we will be used are created and renamed as needed, like for example daily_avgcalories… # Data Analysis and Data Sharing We have discovered an important correlation between a healthy sleep and the physical exercice, people who make average steps per day are likely to sleep well. We found the same trend between sleep and intensity of exercising. People are most likely to use devices that measure at the same time their physical activities,their heart rate and their sleep quality. Take a look on the following graph, but first we will make sure that we have the needed package which is ggplot2. let’s run the code library(ggplot2):

install.packages("ggplot2")
## Installing package into '/cloud/lib/x86_64-pc-linux-gnu-library/4.4'
## (as 'lib' is unspecified)
library(ggplot2)

##Scatter Plot:

ggplot(Daily_records, aes(x=sum_sleep_minute))+
  geom_point(mapping=aes(y=daily_avg_steps,shape="daily_avg_steps",color="daily_avg_steps"))+
  geom_point(mapping=aes(y=daily_avg_intensities,shape="daily_avg_intensities",color="daily_avg_intensities"))+
  geom_point(mapping=aes(y=daily_avg_calories,shape="daily_avg_calories",color="daily_avg_calories"))+
  geom_point(mapping=aes(y=avg_heartrate, color="avg_heartrate",shape="avg_heartrate"))+
  labs(title="variation",x="Sleep",y="Physical Exercice")+
  theme_minimal()

Recommandation

The strategic orientation of the company should be 360 degree, do not focus on one single segment like devices designed to monitoring heart rate for example but focus on all aspects of people’s life, consider offering a one smart solution that can answer all questions about each aspect of customer’s life.