library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.4
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.4.4     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.0
## ✔ 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(ggthemes)
library(ggrepel)
library(xts)
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## 
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
## 
## 
## ######################### Warning from 'xts' package ##########################
## #                                                                             #
## # The dplyr lag() function breaks how base R's lag() function is supposed to  #
## # work, which breaks lag(my_xts). Calls to lag(my_xts) that you type or       #
## # source() into this session won't work correctly.                            #
## #                                                                             #
## # Use stats::lag() to make sure you're not using dplyr::lag(), or you can add #
## # conflictRules('dplyr', exclude = 'lag') to your .Rprofile to stop           #
## # dplyr from breaking base R's lag() function.                                #
## #                                                                             #
## # Code in packages is not affected. It's protected by R's namespace mechanism #
## # Set `options(xts.warn_dplyr_breaks_lag = FALSE)` to suppress this warning.  #
## #                                                                             #
## ###############################################################################
## 
## Attaching package: 'xts'
## 
## The following objects are masked from 'package:dplyr':
## 
##     first, last
library(tsibble)
## 
## Attaching package: 'tsibble'
## 
## The following object is masked from 'package:zoo':
## 
##     index
## 
## The following object is masked from 'package:lubridate':
## 
##     interval
## 
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, union
sensor_data <- read.csv("/Users/manojdannana/Desktop/Manoj/IUPUI/class work/intro to statistics/datasets/Occupancy_Estimation.csv")

Creating a column called mean_temp which has mean of all temperature sensors

sensor_data$mean_temp = rowMeans(sensor_data[, c("S1_Temp", "S2_Temp", "S3_Temp", "S4_Temp")])

Grouping the days

sensor_data$datetime <- as.POSIXct(paste(sensor_data$Date, sensor_data$Time), format = "%d/%m/%y %H:%M:%S")

sensor_data$date_only <- as.Date(sensor_data$datetime)
unique(sensor_data$date_only)
## [1] "2017-12-22" "2017-12-23" "2017-12-24" "2017-12-25" "2017-12-26"
## [6] "2018-01-10" "2018-01-11"
head(sensor_data)
##       Date     Time S1_Temp S2_Temp S3_Temp S4_Temp S1_Light S2_Light S3_Light
## 1 22/12/17 10:49:41   24.94   24.75   24.56   25.38      121       34       53
## 2 22/12/17 10:50:12   24.94   24.75   24.56   25.44      121       33       53
## 3 22/12/17 10:50:42   25.00   24.75   24.50   25.44      121       34       53
## 4 22/12/17 10:51:13   25.00   24.75   24.56   25.44      121       34       53
## 5 22/12/17 10:51:44   25.00   24.75   24.56   25.44      121       34       54
## 6 22/12/17 10:52:14   25.00   24.81   24.56   25.44      121       34       54
##   S4_Light S1_Sound S2_Sound S3_Sound S4_Sound S5_CO2 S5_CO2_Slope S6_PIR
## 1       40     0.08     0.19     0.06     0.06    390    0.7692308      0
## 2       40     0.93     0.05     0.06     0.06    390    0.6461538      0
## 3       40     0.43     0.11     0.08     0.06    390    0.5192308      0
## 4       40     0.41     0.10     0.10     0.09    390    0.3884615      0
## 5       40     0.18     0.06     0.06     0.06    390    0.2538462      0
## 6       40     0.13     0.06     0.06     0.07    390    0.1653846      0
##   S7_PIR Room_Occupancy_Count mean_temp            datetime  date_only
## 1      0                    1   24.9075 2017-12-22 10:49:41 2017-12-22
## 2      0                    1   24.9225 2017-12-22 10:50:12 2017-12-22
## 3      0                    1   24.9225 2017-12-22 10:50:42 2017-12-22
## 4      0                    1   24.9375 2017-12-22 10:51:13 2017-12-22
## 5      0                    1   24.9375 2017-12-22 10:51:44 2017-12-22
## 6      0                    1   24.9525 2017-12-22 10:52:14 2017-12-22

Including all dates now

filtered_data <- sensor_data %>%
  filter(date_only %in% c("2017-12-22", "2017-12-23", "2017-12-24", "2017-12-25", "2017-12-26", "2018-01-10", "2018-01-11"))

Grouping the filtered data for every hour

filtered_data$Time <- as.POSIXct(filtered_data$Time, format = "%H:%M:%S")

grouped_data <- filtered_data %>%
  group_by(minute = minute(Time) %>% as.character()) %>%
  summarize(mean_mean_temp = mean(mean_temp, na.rm = TRUE))
head(grouped_data)
## # A tibble: 6 × 2
##   minute mean_mean_temp
##   <chr>           <dbl>
## 1 0                25.4
## 2 1                25.4
## 3 10               25.5
## 4 11               25.5
## 5 12               25.5
## 6 13               25.5
grouped_data$hour <- as.numeric(grouped_data$minute)

ggplot(grouped_data, aes(x = hour, y = mean_mean_temp)) +
  geom_line() +
  labs(title = "Mean Temperature by Minute", x = "Minute", y = "Mean of Mean Sensor Temperature")

Inferences:

From the above graph we can observe that the Average temperature of the room is at it’s peak in the noon hours and during the nights it slowly starts to decrease. Again after sunrise in the morning it starts to increase.

From this we can identify a Trend for the temperature of the room.

Linear Regression

lm_model <- lm(mean_mean_temp ~ hour, data = grouped_data)

summary(lm_model)
## 
## Call:
## lm(formula = mean_mean_temp ~ hour, data = grouped_data)
## 
## Residuals:
##        Min         1Q     Median         3Q        Max 
## -0.0236659 -0.0066688  0.0006955  0.0060962  0.0178872 
## 
## Coefficients:
##               Estimate Std. Error   t value Pr(>|t|)    
## (Intercept)  2.546e+01  2.164e-03 11767.679  < 2e-16 ***
## hour        -2.557e-04  6.325e-05    -4.043 0.000158 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.008484 on 58 degrees of freedom
## Multiple R-squared:  0.2199, Adjusted R-squared:  0.2064 
## F-statistic: 16.35 on 1 and 58 DF,  p-value: 0.0001576
ggplot(grouped_data, aes(x = hour, y = mean_mean_temp)) +
  geom_point() +  # Add data points
  geom_smooth(method = "lm", se = FALSE) +
  labs(title = "Mean Temperature by Hour", x = "Hour", y = "Mean of Mean Sensor Temperature")
## `geom_smooth()` using formula = 'y ~ x'

As I suspected above, there is clear Upward Trend during the day from 7 AM - 3 PM in the evening. In the evening there seems to be fluctuation in temperature reading in a small range as expected. Again in the night time we can see a Downward Trend from 7 PM - 6 AM.

These Trends are as expected from our common sense.

library(forecast)
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
sensor_data$Time <- as.POSIXct(sensor_data$Time, format = "%H:%M:%S")

sensor_ts <- ts(sensor_data$mean_temp, frequency = 24)  

decomp <- decompose(sensor_ts, type = "multiplicative")

acf(decomp$seasonal, main = "ACF of Seasonal Component")

pacf(decomp$seasonal, main = "PACF of Seasonal Component")

From the above ACF Plot we can see that there are 2 spikes which means that there are two seasons in the data.