Seven Tools Analysis
2025-05-05
1 Case Study about Personal Life using 7 QC Tools
Problem Statement:
Dalam kehidupan sehari-hari, sering kali kita merasa kelelahan, kurang produktif, atau tidak mencapai target pribadi meskipun sudah menjalani rutinitas yang terasa sibuk. Untuk mengatasi hal ini secara sistematis, kita menggunakan 7 QC Tools untuk mengidentifikasi, menganalisis, dan mengatasi akar permasalahannya.
Tujuan Analisis:
Meningkatkan kualitas hidup pribadi dengan cara:
✅Mengidentifikasi aktivitas yang menyita waktu paling banyak
✅Menganalisis hubungan antara tidur dan energi
✅Menelusuri penyebab utama stres dan kelelahan
✅Menstabilkan berat badan secara mingguan
✅Mengatur keuangan harian lebih baik
1.1 Data Dummy
Variabel:
Tanggal (Date)
Durasi Tidur (Sleep_Duration:jam)
Level Energi (Energy_Level: skala 1-10)
Jenis Aktivitas Harian (Activity_Type: tidur, kerja, olahraga, dsb)
Durasi Aktivitas (jam) (Activity_hours)
Berat Badan Mingguan (Weight_Weekly)
Biaya Harian (Daily_Expense)
Penyebab Stres (Stress_Causes)
# Ensure all required packages are installed
packages <- c("dplyr", "stringi", "lubridate", "DT")
new_packages <- packages[!(packages %in% installed.packages()[, "Package"])]
if(length(new_packages)) install.packages(new_packages)
# Load libraries
library(dplyr)
library(stringi)
library(lubridate)
library(DT)
# Set seed & generate dates
set.seed(123)
n <- 180 # 6 months of data
dates <- seq.Date(from = as.Date("2024-01-01"), by = "day", length.out = n)
# Generate dummy data
sleep_duration <- round(rnorm(n, mean = 6.5, sd = 1.2), 1)
energy_level <- round(10 - abs(sleep_duration - 7) + rnorm(n, 0, 1), 1)
energy_level <- pmax(pmin(energy_level, 10), 1)
activity_types <- c("Work", "Exercise", "Sleep", "Leisure", "Housework")
activity_data <- sample(activity_types, n, replace = TRUE)
activity_hours <- round(runif(n, 0.5, 8), 1)
weekly_weight <- round(rnorm(n, mean = 65, sd = 3), 1)
daily_expense <- round(rnorm(n, mean = 100000, sd = 25000), 0)
stress_causes <- c("Workload", "Lack of sleep", "Traffic", "Deadlines", "Financial")
stress_cause <- sample(stress_causes, n, replace = TRUE)
# Combine into one dataset
personal_life_data <- tibble(
Date = dates,
Sleep_Duration = sleep_duration,
Energy_Level = energy_level,
Activity_Type = activity_data,
Activity_Hours = activity_hours,
Weight_Weekly = weekly_weight,
Daily_Expense = daily_expense,
Stress_Cause = stress_cause
)
# Show the dataset
datatable(
personal_life_data,
extensions = 'Buttons',
options = list(
dom = 'Bfrtip',
buttons = c('copy', 'csv', 'excel', 'pdf', 'print'),
scrollY = "400px",
scrollCollapse = TRUE,
paging = FALSE
),
caption = htmltools::tags$caption(
style = 'caption-side: top; text-align: left;
font-size: 18px; font-weight: bold;',
"Personal Life Monitoring Dataset"
),
class = 'stripe hover compact'
)1.2 Checksheet
Tujuan:
Mencatat variabel kesehatan harian secara menyeluruh guna mengidentifikasi pola, anomali, dan faktor-faktor yang berpengaruh terhadap kondisi fisik dan kesejahteraan.
Variabel yang Dicatat:
Tanggal
Usia
BMI (Indeks Massa Tubuh)
Tekanan Darah (Sistolik)
Kadar Kolesterol (mg/dL)
Kadar Glukosa (mg/dL)
Denyut Jantung (bpm)
Lokasi Tinggal
Kondisi Kesehatan Umum
(Seperti: Sehat, Hipertensi, Diabetes, Obesitas, Penyakit Kardiovaskular)
*Musim (Hujan, Kemarau, Peralihan)**
Alasan Mencatat Semua Variabel: - Memberikan konteks lengkap untuk analisis mendalam di tahap selanjutnya (Histogram, Scatter Diagram, Control Chart, dll). - Mengidentifikasi pola interaksi antar variabel (misalnya hubungan antara tekanan darah dan musim). - Memungkinkan pembuatan multi-dimensional insights untuk pengambilan keputusan terkait gaya hidup atau kesehatan.
1.2.1 Data Check Sheet
Data mentah yang berisi catatan penyebab stres harian dalam kehidupan pribadi yang berguna untuk mendeteksi frekuensi dan pola:
# Tampilkan data hanya kolom tanggal dan penyebab stres
checksheet_data <- personal_life_data %>%
select(Date, Stress_Cause)
datatable(
checksheet_data,
extensions = 'Buttons',
options = list(
dom = 'Bfrtip',
buttons = c('copy', 'csv', 'excel', 'pdf', 'print'),
pageLength = 10
),
caption = htmltools::tags$caption(
style = 'caption-side: top; text-align: left;
font-size: 18px; font-weight: bold;',
"Check Sheet – Catatan Harian Penyebab Stres"
),
class = 'stripe hover compact'
)1.2.2 Frequency Tabulation:
Menampilkan jumlah kemunculan masing-masing penyebab stres dalam periode 6 bulan:
# Tabulasi frekuensi penyebab stres
stress_freq <- personal_life_data %>%
count(Stress_Cause, sort = TRUE)
datatable(
stress_freq,
colnames = c("Penyebab Stres", "Frekuensi"),
caption = htmltools::tags$caption(
style = 'caption-side: top; text-align: left;
font-size: 18px; font-weight: bold;',
"Check Sheet – Frekuensi Penyebab Stres"
),
class = 'stripe hover compact'
)1.2.3 Simple Visualization
# Pastikan plotly sudah terpasang
if(!require(plotly)) install.packages("plotly")
library(plotly)
# Rename untuk konsistensi
reason_summary <- personal_life_data %>%
count(Stress_Cause, name = "Frequency") %>%
rename(Reason = Stress_Cause)
# Plot interaktif horizontal
plot_ly(
reason_summary,
x = ~Frequency,
y = ~reorder(Reason, Frequency),
type = 'bar',
orientation = 'h',
marker = list(
color = ~Frequency,
colorscale = 'twilight', # Ganti dengan twilight sesuai permintaan
showscale = TRUE
)
) %>%
layout(
title = list(text = "Check Sheet: Frekuensi Penyebab Stres", font = list(size = 18)),
xaxis = list(title = "Frekuensi"),
yaxis = list(title = "Penyebab"),
margin = list(l = 120)
)1.3 Histogram
Untuk melihat distribusi waktu olahraga dalam sebulan. Dengan ini, kita bisa mengevaluasi apakah waktu olahraga kamu sudah konsisten atau masih fluktuatif.
# Pastikan plotly terinstal
if(!require(plotly)) install.packages("plotly")
library(plotly)
# Filter aktivitas olahraga selama 30 hari terakhir
exercise_data <- personal_life_data %>%
filter(Activity_Type == "Exercise") %>%
filter(Date >= max(Date) - lubridate::days(30))
# Ambil hanya nilai jam aktivitas
exercise_hours <- exercise_data$Activity_Hours
# Hitung kurva densitas
density_data <- density(exercise_hours)
# Plot histogram interaktif dengan density curve
plot_ly() %>%
add_trace(
x = exercise_hours,
type = 'histogram',
name = 'Durasi Olahraga',
nbinsx = 20,
marker = list(
color = 'lightblue',
line = list(color = 'black', width = 1)
),
opacity = 0.6
) %>%
add_trace(
x = density_data$x,
y = density_data$y * length(exercise_hours) * diff(range(exercise_hours)) / 20, # Scaling
type = 'scatter',
mode = 'lines',
name = 'Kurva Densitas',
line = list(color = 'darkblue', width = 3)
) %>%
layout(
title = 'Histogram Interaktif – Durasi Olahraga (30 Hari Terakhir)',
xaxis = list(title = 'Durasi (Jam)', showgrid = FALSE),
yaxis = list(title = 'Frekuensi / Densitas', showgrid = FALSE),
bargap = 0.1,
plot_bgcolor = 'white',
paper_bgcolor = 'white',
legend = list(
orientation = 'v',
x = 0.98,
xanchor = 'right',
y = 0.98,
yanchor = 'top',
bgcolor = 'rgba(255,255,255,0.8)',
bordercolor = 'black',
borderwidth = 0.3
)
)1.4 Pareto Chart
untuk mengidentifikasi prioritas utama dari berbagai penyebab atau kategori berdasarkan dampaknya
# Load libraries
library(dplyr)
library(plotly)
library(RColorBrewer)
# Summarize the time spent on each activity
pareto_data <- personal_life_data %>%
group_by(Activity_Type) %>%
summarise(total_hours = sum(Activity_Hours)) %>%
arrange(desc(total_hours)) %>%
mutate(
cum_freq = cumsum(total_hours) / sum(total_hours) * 100 # cumulative percentage
)
# Create different colors for each Activity_Type
colors <- RColorBrewer::brewer.pal(n = length(pareto_data$Activity_Type), name = "Set3")
# Create Plotly Pareto Chart
fig <- plot_ly()
# Add Bar Chart (Total Hours) - with different colors
fig <- fig %>% add_bars(
x = ~reorder(pareto_data$Activity_Type, -pareto_data$total_hours),
y = ~pareto_data$total_hours,
name = 'Total Hours Spent',
marker = list(color = colors),
yaxis = "y1"
)
# Add Cumulative Line
fig <- fig %>% add_lines(
x = ~reorder(pareto_data$Activity_Type, -pareto_data$total_hours),
y = ~pareto_data$cum_freq,
name = 'Cumulative (%)',
yaxis = "y2",
line = list(color = 'red', dash = 'dash')
)
# Add Cut-off Line at 80%
fig <- fig %>% add_lines(
x = ~reorder(pareto_data$Activity_Type, -pareto_data$total_hours),
y = rep(80, length(pareto_data$Activity_Type)),
name = 'Cut-off 80%',
yaxis = "y2",
line = list(color = 'green', dash = 'dot')
)
# Adjust layout
fig <- fig %>% layout(
title = "Pareto Chart - Time Spent on Daily Activities",
xaxis = list(
title = "Activity Type",
tickangle = -45 # tilt 45 degrees
),
yaxis = list(title = "Total Hours Spent"),
yaxis2 = list(
title = "Cumulative (%)",
overlaying = "y",
side = "right",
range = c(0, 100)
),
legend = list(x = 0.8, y = 0.75),
shapes = list(
list(
type = "line",
x0 = -0.5,
x1 = length(pareto_data$Activity_Type) - 0.5,
y0 = 80,
y1 = 80,
yref = "y2",
line = list(color = "green", width = 2, dash = "dot")
)
)
)
# Show chart
fig1.5 Fishbone
untuk mengidentifikasi akar penyebab dari stres atau rasa lelah yang sering muncul dalam kehidupan pribadi, menggunakan pendekatan visual Fishbone Diagram (Diagram Ishikawa). Data yang digunakan berasal dari pemantauan harian selama enam bulan.
if (!require(DiagrammeR)) install.packages("DiagrammeR")
library(DiagrammeR)
grViz("
digraph fishbone {
graph [rankdir = LR, layout = dot]
node [shape = box, style = filled, fillcolor = lightgray]
main [label = 'Stress / Fatigue', shape = ellipse, fillcolor = lightblue, fontsize=14]
work [label = 'Work']
physical [label = 'Physical']
environment [label = 'Environment']
financial [label = 'Financial']
workload [label = 'Workload']
deadlines [label = 'Deadlines']
sleep [label = 'Lack of Sleep']
traffic [label = 'Traffic']
money [label = 'Financial Issues']
main -> work
main -> physical
main -> environment
main -> financial
work -> workload
work -> deadlines
physical -> sleep
environment -> traffic
financial -> money
}
")if (!require(DiagrammeR)) install.packages("DiagrammeR")
library(DiagrammeR)
grViz("
digraph fishbone {
graph [layout = dot, rankdir = LR]
node [fontname=Helvetica, fontsize=22, style=filled]
# Masalah utama
Problem [label='Stress / Fatigue', shape=ellipse, fillcolor=lightblue, width=5.0, height=1.2]
# Kategori utama
node [shape=diamond, width=2.5, height=1.0, fillcolor='#FFD700']
A1 [label='Work']
A2 [label='Physical']
A3 [label='Environment']
A4 [label='Financial']
A5 [label='Social']
A6 [label='Lifestyle']
# Subfaktor
node [shape=ellipse, width=2.5, height=0.6, fillcolor='#90EE90']
A1a [label='Heavy Workload']
A1b [label='Tight Deadlines']
A2a [label='Lack of Sleep']
A2b [label='Poor Diet']
A3a [label='Traffic']
A3b [label='Noise Pollution']
A4a [label='Debt Pressure']
A4b [label='Low Income']
A5a [label='Family Conflict']
A5b [label='Lack of Support']
A6a [label='Lack of Exercise']
A6b [label='Poor Time Management']
# Hubungan utama ke kategori
A1 -> Problem
A2 -> Problem
A3 -> Problem
A4 -> Problem
A5 -> Problem
A6 -> Problem
# Subfaktor ke kategori
A1a -> A1
A1b -> A1
A2a -> A2
A2b -> A2
A3a -> A3
A3b -> A3
A4a -> A4
A4b -> A4
A5a -> A5
A5b -> A5
A6a -> A6
A6b -> A6
}
")1.6 Scatter Diagram
untuk melihat apakah ada tren atau korelasi yang jelas antara kedua variabel tersebut. Apakah durasi tidur yang lebih lama berhubungan dengan level energi yang lebih tinggi? Dengan menambahkan garis regresi linier, scatter plot ini juga menunjukkan apakah hubungan itu linear atau tidak.
# Install dan load paket yang dibutuhkan
if (!require(plotly)) install.packages("plotly")
library(plotly)
# Buat data contoh dengan hubungan antara durasi tidur dan level energi
set.seed(42) # Untuk reprodusibilitas
data_tidur_energi <- data.frame(
Durasi_Tidur = c(5, 6, 7, 8, 9, 10, 11, 5.5, 6.5, 7.5,
8.5, 9.5, 6, 7, 8, 9, 10, 11, 6.5, 7.5),
Level_Energi = c(3, 4, 5, 6, 7, 8, 9, 3.5, 4.5, 5.5,
6.5, 7.5, 4, 5, 6, 7, 8, 9, 4.5, 5.5)
)
# Menambahkan sedikit noise untuk mendapatkan korelasi sekitar 0.8
data_tidur_energi$Level_Energi <- data_tidur_energi$Level_Energi + rnorm(n = 20, mean = 0, sd = 0.5)
# Hitung koefisien korelasi antara durasi tidur dan level energi
korelasi_value <- cor(data_tidur_energi$Durasi_Tidur, data_tidur_energi$Level_Energi)
# Buat scatter plot menggunakan Plotly dengan garis regresi linier
fig <- plot_ly(data_tidur_energi,
x = ~Durasi_Tidur,
y = ~Level_Energi,
type = 'scatter',
mode = 'markers',
marker = list(color = 'blue', size = 10)) %>%
add_lines(x = data_tidur_energi$Durasi_Tidur,
y = predict(lm(Level_Energi ~ Durasi_Tidur, data = data_tidur_energi)),
line = list(color = 'red', dash = 'solid', width = 2)) %>%
layout(title = paste("Scatter Plot: Durasi Tidur vs Level Energi\nKorelasi: ", round(korelasi_value, 2)),
xaxis = list(title = "Durasi Tidur (Jam)"),
yaxis = list(title = "Level Energi (Skala 1-10)"))
# Tampilkan plot
fig1.7 Control Chart
untuk memantau apakah berat badan mingguan berada dalam batas kontrol statistik yang sehat dan stabil. Ini membantu mendeteksi perubahan signifikan yang mungkin perlu tindakan, seperti pola makan atau olahraga.
# Install dan load paket yang dibutuhkan
if (!require(plotly)) install.packages("plotly")
library(plotly)
library(dplyr)
library(lubridate)
# Agregasi data berat badan per minggu
weekly_weight_data <- personal_life_data %>%
mutate(Week = floor_date(Date, unit = "week")) %>%
group_by(Week) %>%
summarise(Avg_Weight = mean(Weight_Weekly)) %>%
ungroup()
# Tentukan batas kendali
CL <- mean(weekly_weight_data$Avg_Weight)
UCL <- CL + 2 * sd(weekly_weight_data$Avg_Weight) # Upper control limit (UCL)
LCL <- CL - 2 * sd(weekly_weight_data$Avg_Weight) # Lower control limit (LCL)
# Tandai outliers
weekly_weight_data <- weekly_weight_data %>%
mutate(Outlier = ifelse(Avg_Weight > UCL | Avg_Weight < LCL, "Ya", "Tidak"))
# Buat plot dengan Plotly
plot_ly(weekly_weight_data, x = ~Week, y = ~Avg_Weight, type = 'scatter', mode = 'lines+markers',
line = list(color = 'blue'),
marker = list(size = 8, color = ifelse(weekly_weight_data$Outlier == "Ya", "red", "blue")),
hoverinfo = 'text',
text = ~paste("Minggu:", format(Week, "%d-%b-%Y"), "<br>Rata-rata Berat:", round(Avg_Weight, 1), "kg")) %>%
add_lines(y = rep(CL, length(weekly_weight_data$Week)), name = "CL", line = list(color = 'green', dash = 'dot')) %>%
add_lines(y = rep(UCL, length(weekly_weight_data$Week)), name = "UCL", line = list(color = 'red', dash = 'dot')) %>%
add_lines(y = rep(LCL, length(weekly_weight_data$Week)), name = "LCL", line = list(color = 'red', dash = 'dot')) %>%
layout(title = "Control Chart – Weekly Average Weight Tracking",
xaxis = list(title = "Minggu"),
yaxis = list(title = "Berat Mingguan (kg)"),
legend = list(orientation = 'h', x = 0.3, y = -0.2))1.8 Flowchart
library(DiagrammeR)
grViz("
digraph daily_routine {
graph [layout=dot]
node [style=filled, fontname='Helvetica']
# Bagian kiri
subgraph cluster_left {
label = 'Pagi - Siang'
rankdir = TB
Start [label='Start', shape=ellipse, fillcolor=orange]
Wake [label='Wake Up', shape=box, fillcolor=lightblue]
Alarm [label='Alarm Rings', shape=box, fillcolor=lightblue]
OnTime [label='On Time Check', shape=box, fillcolor=lightblue]
MorningRoutine [label='Morning Routine', shape=box, fillcolor=lightblue]
Shower [label='Shower', shape=box, fillcolor=lightblue]
Breakfast [label='Breakfast', shape=box, fillcolor=lightblue]
WorkMorning [label='Work (Morning)', shape=box, fillcolor=lightblue]
StayFocused [label='Focus Level', shape=box, fillcolor=lightblue]
Meeting [label='Meetings', shape=box, fillcolor=lightblue]
BreakTime [label='Break Time', shape=box, fillcolor=lightblue]
Connector1 [label='', shape=circle, width=0.3, fillcolor=gray]
Start -> Wake -> Alarm -> OnTime -> MorningRoutine
MorningRoutine -> Shower -> Breakfast -> WorkMorning
WorkMorning -> StayFocused -> Meeting -> BreakTime -> Connector1
}
# Bagian kanan
subgraph cluster_right {
label = 'Siang - Malam'
rankdir = TB
Connector2 [label='', shape=circle, width=0.3, fillcolor=gray]
Lunch [label='Lunch', shape=box, fillcolor=lightblue]
Scroll [label='Scroll Phone', shape=box, fillcolor=lightblue]
Chat [label='Chat with Friends', shape=box, fillcolor=lightblue]
WorkAfternoon [label='Work (Afternoon)', shape=box, fillcolor=lightblue]
ResumeWork [label='Resume Work', shape=box, fillcolor=lightblue]
Tired [label='Feeling Tired', shape=box, fillcolor=lightblue]
EveningRoutine [label='Evening Routine', shape=box, fillcolor=lightblue]
Dinner [label='Dinner', shape=box, fillcolor=lightblue]
Relax [label='Relax / Netflix', shape=box, fillcolor=lightblue]
TrySleep [label='Try to Sleep', shape=box, fillcolor=lightblue]
Sleep [label='Go to Sleep', shape=box, fillcolor=lightblue]
End [label='Finish', shape=ellipse, fillcolor=orange]
Connector2 -> Lunch -> Scroll -> Chat -> WorkAfternoon
WorkAfternoon -> ResumeWork -> Tired -> EveningRoutine
EveningRoutine -> Dinner -> Relax -> TrySleep -> Sleep -> End
}
# Sambungan horizontal
Connector1 -> Connector2 [arrowhead=none, style=dashed, constraint=false]
}
")