Human Resource Management plays an important role in any organization and business to evaluate the company’s growth and performance based on the employees. This helps in analyzing the human assets working in a company and how they can be motivated to do better by different means. Human Resource Management helps in deriving useful information from employee data to make the working environment better and more efficient. This article will guide you through the steps to build a dashboard for human resource management analytics in the R programming language.
Importance of Human Resource Management (HRM) in an OrganizationThere are various needs for having HRM in a company:
- Talent Acquisition and Retention: HR Management helps in keeping good talent in the company.
- Employee Development: Focuses on continuous employee training and development, enhancing skills and career growth.
- Performance Management: Implements performance appraisal systems to evaluate and improve employee productivity.
- Workplace Culture: Fosters a positive work environment, improving employee satisfaction and engagement which helps them grow and increases productivity.
- Compensation and Benefits: Designs competitive compensation packages to attract and retain top talent.
Now we will discuss step by step to create Human Resource Management Analytics Dashboard in R Programming Language.
Step 1. Load libraries and DatasetReplace the path of the dataset from the original one. We are using multiple libraries to make our task easier. ggplot2 helps in the visualization of our data.
Dataset Link: Human Resource Management Analytics
This dataset contains 1480 observations and 38 variables, representing various employee attributes and metrics.
R
# Load necessary libraries
library(dplyr)
library(ggplot2)
library(lubridate)
# Load the dataset
data <- read.csv("hr_data.csv")
head(data)
Output:
EmpID Age AgeGroup Attrition BusinessTravel DailyRate Department
1 RM297 18 18-25 Yes Travel_Rarely 230 Research & Development
2 RM302 18 18-25 No Travel_Rarely 812 Sales
3 RM458 18 18-25 Yes Travel_Frequently 1306 Sales
4 RM728 18 18-25 No Non-Travel 287 Research & Development
5 RM829 18 18-25 Yes Non-Travel 247 Research & Development
6 RM973 18 18-25 No Non-Travel 1124 Research & Development
DistanceFromHome Education EducationField EmployeeCount EmployeeNumber
1 3 3 Life Sciences 1 405
2 10 3 Medical 1 411
3 5 3 Marketing 1 614
4 5 2 Life Sciences 1 1012
5 8 1 Medical 1 1156
6 1 3 Life Sciences 1 1368
EnvironmentSatisfaction Gender HourlyRate JobInvolvement JobLevel JobRole
1 3 Male 54 3 1 Laboratory Technician
2 4 Female 69 2 1 Sales Representative
3 2 Male 69 3 1 Sales Representative
4 2 Male 73 3 1 Research Scientist
5 3 Male 80 3 1 Laboratory Technician
6 4 Female 97 3 1 Laboratory Technician
JobSatisfaction MaritalStatus MonthlyIncome SalarySlab MonthlyRate NumCompaniesWorked
1 3 Single 1420 Upto 5k 25233 1
2 3 Single 1200 Upto 5k 9724 1
3 2 Single 1878 Upto 5k 8059 1
4 4 Single 1051 Upto 5k 13493 1
5 3 Single 1904 Upto 5k 13556 1
6 4 Single 1611 Upto 5k 19305 1
Over18 OverTime PercentSalaryHike PerformanceRating RelationshipSatisfaction
1 Y No 13 3 3
2 Y No 12 3 1
3 Y Yes 14 3 4
4 Y No 15 3 4
5 Y No 12 3 4
6 Y No 15 3 3
StandardHours StockOptionLevel TotalWorkingYears TrainingTimesLastYear WorkLifeBalance
1 80 0 0 2 3
2 80 0 0 2 3
3 80 0 0 3 3
4 80 0 0 2 3
5 80 0 0 0 3
6 80 0 0 5 4
YearsAtCompany YearsInCurrentRole YearsSinceLastPromotion YearsWithCurrManager
1 0 0 0 0
2 0 0 0 0
3 0 0 0 0
4 0 0 0 0
5 0 0 0 0
6 0 0 0 0 Step 2. Data PreprocessingData preprocessing is a crucial step to ensure the data is clean and ready for analysis. Here, we will handle missing values, convert data types, and create new variables as needed.
R
# Check for missing values
sum(is.na(data))
# Ensure there are no missing values
if (sum(is.na(data)) > 0) {
data <- na.omit(data)
}
Output:
[1] 57 Step 3. Exploratory Data Analysis (EDA)This step is important to identify and explore the dataset so that we can analyze it and make informed decisions. Here, we will create multiple such visualization to understand better.
R
# Gender distribution pie chart
gender_distribution <- data %>%
group_by(Gender) %>%
summarise(Count = n()) %>%
mutate(Percentage = round(Count / sum(Count) * 100, 1))
# Plot
ggplot(gender_distribution, aes(x = "", y = Percentage, fill = Gender)) +
geom_bar(width = 1, stat = "identity") +
coord_polar("y", start = 0) +
theme_void() +
geom_text(aes(label = paste0(Percentage, "%")),
position = position_stack(vjust = 0.5)) +
labs(title = "Gender Distribution of Employees") +
scale_fill_brewer(palette = "Set3")
Output:
 Human Resource Management Analytics Dashboard in R This pie chart indicates that the total employees of the given company has 60% male employees and 40% female.
Education Level of EmployeesNow we will visualize the Education Level of Employees.
R
# Education Level Distribution
library(ggplot2)
ggplot(data, aes(x = factor(Education, levels = c(1, 2, 3, 4, 5)),
fill = factor(Education))) +
geom_bar() +
labs(title = "Distribution of Education Levels",
x = "Education Level",
y = "Number of Employees",
fill = "Education Level") +
scale_x_discrete(labels = c("1" = "Below College", "2" = "College", "3" = "Bachelor",
"4" = "Master", "5" = "Doctor"))
Output:
 Human Resource Management Analytics Dashboard in R Employee Age distributionThis will give us insights about the age group of the employees.
R
# Employee Age Distribution
ggplot(data, aes(x = Age)) +
geom_histogram(binwidth = 5, fill = "green", color = "black") +
labs(title = "Age Distribution of Employees",
x = "Age",
y = "Count")
Output:
 Human Resource Management Analytics Dashboard in R As we can see that the age group from 30-40 have the highest number of employees.
Job Role DistributionThis explains us the kind of jobs provided and the number of employees in the certain sector.
R
# Job Role Distribution
ggplot(data, aes(x = JobRole, fill = JobRole)) +
geom_bar() +
labs(title = "Distribution of Job Roles",
x = "Job Role",
y = "Count") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
Output:
 Human Resource Management Analytics Dashboard in R The highest number of job roles in the company is sales executive.
Monthly Income DsitributionThis helps us analyze the income of the employees.
R
# Monthly Income Distribution
ggplot(data, aes(x = MonthlyIncome)) +
geom_histogram(binwidth = 1000, fill = "purple", color = "black") +
labs(title = "Distribution of Monthly Income",
x = "Monthly Income",
y = "Count")
Output:
 Human Resource Management Analytics Dashboard in R Department-wise Gender DistributionThis plot will help us estimate the gender ratio in the company for better hiring to maintain equality and diversity.
R
# Department-wise Gender Distribution
ggplot(data, aes(x = Department, fill = Gender)) +
geom_bar(position = "fill") +
scale_y_continuous(labels = scales::percent) +
labs(title = "Gender Distribution by Department",
x = "Department",
y = "Percentage",
fill = "Gender") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
Output:
 Human Resource Management Analytics Dashboard in R As we can see the least number of female employee is in Human resource department.
Dashboard Analysis for HR ManagementA well-designed HR Management Analytics Dashboard provides critical insights into various aspects of the workforce, enabling better management and strategic planning.
Department Based Dashboard for overviewHere we will build a dashboard which will help us navigate through different department and get all the necessary insights related to including an overview, employee engagement and attrition analysis.
R
library(shiny)
library(ggplot2)
library(shinydashboard)
ui <- fluidPage(
titlePanel("HR Management Analytics Dashboard"),
sidebarLayout(
sidebarPanel(
selectInput("department", "Select Department:",
choices = unique(data$Department))
),
mainPanel(
tabsetPanel(
tabPanel("Overview",
fluidRow(
valueBoxOutput("total_employees"),
valueBoxOutput("avg_salary"),
valueBoxOutput("avg_age")
),
plotOutput("gender_distribution"),
plotOutput("age_distribution"),
plotOutput("education_distribution"),
plotOutput("attrition_by_dept"),
plotOutput("job_satisfaction"),
plotOutput("performance_ratings"),
plotOutput("training_times")
),
tabPanel("Employee Engagement",
plotOutput("engagement_by_dept"),
plotOutput("years_with_manager"),
plotOutput("work_life_balance")
),
tabPanel("Attrition Analysis",
plotOutput("attrition_by_age"),
plotOutput("attrition_by_job_role"),
plotOutput("attrition_by_gender")
)
)
)
)
)
server <- function(input, output) {
filtered_data <- reactive({
data[data$Department == input$department, ]
})
output$total_employees <- renderValueBox({
valueBox(
nrow(filtered_data()), "Total Employees", icon = icon("users"),
color = "blue"
)
})
output$avg_salary <- renderValueBox({
avg_salary <- round(mean(filtered_data()$MonthlyIncome), 2)
valueBox(
avg_salary, "Average Salary", icon = icon("dollar-sign"),
color = "green"
)
})
output$avg_age <- renderValueBox({
avg_age <- round(mean(filtered_data()$Age), 2)
valueBox(
avg_age, "Average Age", icon = icon("calendar-alt"),
color = "purple"
)
})
output$gender_distribution <- renderPlot({
gender_dist <- table(filtered_data()$Gender)
pie(gender_dist, main="Gender Distribution",
col=c("pink", "lightblue"), labels=paste0(names(gender_dist), "\n",
round(prop.table(gender_dist)*100, 2), "%"))
})
output$age_distribution <- renderPlot({
ggplot(filtered_data(), aes(x=Age)) +
geom_histogram(binwidth=5, fill="blue", color="black") +
labs(title="Age Distribution", x="Age", y="Count")
})
output$education_distribution <- renderPlot({
ggplot(filtered_data(), aes(x=EducationField)) +
geom_bar(fill="orange", color="black") +
labs(title="Education Distribution", x="Education Field", y="Count")
})
output$attrition_by_dept <- renderPlot({
ggplot(filtered_data(), aes(x=Department, fill=Attrition)) +
geom_bar(position="fill") +
labs(title="Attrition by Department", x="Department", y="Proportion")
})
output$job_satisfaction <- renderPlot({
ggplot(filtered_data(), aes(x=JobSatisfaction)) +
geom_bar(fill="green", color="black") +
labs(title="Job Satisfaction Levels", x="Job Satisfaction", y="Count")
})
output$performance_ratings <- renderPlot({
ggplot(filtered_data(), aes(x=PerformanceRating)) +
geom_bar(fill="purple", color="black") +
labs(title="Performance Ratings Distribution", x="Performance Rating", y="Count")
})
output$training_times <- renderPlot({
ggplot(filtered_data(), aes(x=TrainingTimesLastYear)) +
geom_bar(fill="orange", color="black") +
labs(title="Training Times Last Year", x="Training Times", y="Count")
})
output$engagement_by_dept <- renderPlot({
ggplot(filtered_data(), aes(x=Department, y=JobInvolvement)) +
geom_boxplot(fill="lightblue", color="black") +
labs(title="Employee Engagement by Department", x="Department", y="Job Involvement")
})
output$years_with_manager <- renderPlot({
ggplot(filtered_data(), aes(x=YearsWithCurrManager)) +
geom_histogram(binwidth=1, fill="lightgreen", color="black") +
labs(title="Years with Current Manager", x="Years", y="Count")
})
output$work_life_balance <- renderPlot({
ggplot(filtered_data(), aes(x=WorkLifeBalance)) +
geom_bar(fill="lightcoral", color="black") +
labs(title="Work-Life Balance", x="Work-Life Balance", y="Count")
})
output$attrition_by_age <- renderPlot({
ggplot(filtered_data(), aes(x=Age, fill=Attrition)) +
geom_histogram(binwidth=5, position="dodge") +
labs(title="Attrition by Age", x="Age", y="Count")
})
output$attrition_by_job_role <- renderPlot({
ggplot(filtered_data(), aes(x=JobRole, fill=Attrition)) +
geom_bar(position="fill") +
labs(title="Attrition by Job Role", x="Job Role", y="Proportion")
})
output$attrition_by_gender <- renderPlot({
ggplot(filtered_data(), aes(x=Gender, fill=Attrition)) +
geom_bar(position="fill") +
labs(title="Attrition by Gender", x="Gender", y="Proportion")
})
}
shinyApp(ui, server)
Output:
 Overview of the Dashboard of resource and development department Here we can navigate and find different insights on the particular department. With the help of the toggle bar we can select the department we want.
Employee analysis based on the department and timeThe UI layout consists of a title, a sidebar for navigation, and a main panel for displaying the plots and metrics. The sidebar allows navigation through different departments and time periods.
R
library(shiny)
library(ggplot2)
library(dplyr)
# Load your dataset
# data <- read.csv("path_to_your_dataset.csv")
ui <- fluidPage(
titlePanel("HR Management Analytics Dashboard"),
sidebarLayout(
sidebarPanel(
selectInput("department", "Select Department:",
choices = unique(data$Department)),
selectInput("time_period", "Select Time Period:",
choices = c("Last Month", "Last Quarter", "Last Year"))
),
mainPanel(
tabsetPanel(
tabPanel("Overview",
fluidRow(
valueBoxOutput("total_employees"),
valueBoxOutput("avg_salary"),
valueBoxOutput("avg_age")
),
fluidRow(
valueBoxOutput("gender_distribution"),
valueBoxOutput("marital_status_distribution"),
valueBoxOutput("job_level_distribution")
),
plotOutput("age_distribution"),
plotOutput("experience_distribution")
),
tabPanel("Performance",
plotOutput("performance_by_department"),
plotOutput("performance_by_age"),
plotOutput("performance_by_experience")
),
tabPanel("Engagement",
plotOutput("engagement_by_gender"),
plotOutput("engagement_by_marital_status"),
plotOutput("engagement_by_job_level")
),
tabPanel("Attrition",
plotOutput("attrition_by_age"),
plotOutput("attrition_by_department"),
plotOutput("attrition_by_experience")
)
)
)
)
)
server <- function(input, output) {
filtered_data <- reactive({
data %>% filter(Department == input$department)
})
output$total_employees <- renderValueBox({
valueBox(
nrow(filtered_data()), "Total Employees", icon = icon("users"),
color = "blue"
)
})
output$avg_salary <- renderValueBox({
avg_salary <- round(mean(filtered_data()$Salary), 2)
valueBox(
avg_salary, "Avg Salary", icon = icon("dollar-sign"),
color = "green"
)
})
output$avg_age <- renderValueBox({
avg_age <- round(mean(filtered_data()$Age), 2)
valueBox(
avg_age, "Avg Age", icon = icon("calendar"),
color = "purple"
)
})
output$gender_distribution <- renderPlot({
ggplot(filtered_data(), aes(x = "", fill = Gender)) +
geom_bar(width = 1) +
coord_polar(theta = "y") +
labs(title = "Gender Distribution", x = "", y = "") +
scale_fill_manual(values = c("Male" = "blue", "Female" = "pink")) +
theme_void() +
geom_text(aes(label = paste0(round((..count..)/sum(..count..)*100), "%")),
stat = "count", position = position_stack(vjust = 0.5))
})
output$marital_status_distribution <- renderPlot({
ggplot(filtered_data(), aes(x = MaritalStatus, fill = MaritalStatus)) +
geom_bar() +
labs(title = "Marital Status Distribution", x = "Marital Status", y = "Count") +
scale_fill_manual(values = c("Single" = "red", "Married" = "green",
"Divorced" = "orange"))
})
output$job_level_distribution <- renderPlot({
ggplot(filtered_data(), aes(x = JobLevel, fill = JobLevel)) +
geom_bar() +
labs(title = "Job Level Distribution", x = "Job Level", y = "Count")
})
output$age_distribution <- renderPlot({
ggplot(filtered_data(), aes(x = Age)) +
geom_histogram(binwidth = 1, fill = "blue", color = "black") +
labs(title = "Age Distribution", x = "Age", y = "Count")
})
output$experience_distribution <- renderPlot({
ggplot(filtered_data(), aes(x = TotalWorkingYears)) +
geom_histogram(binwidth = 1, fill = "green", color = "black") +
labs(title = "Total Working Years Distribution", x = "Total Working Years",
y = "Count")
})
output$performance_by_department <- renderPlot({
ggplot(filtered_data(), aes(x = Department, y = PerformanceRating, fill = Department)) +
geom_boxplot() +
labs(title = "Performance by Department", x = "Department",
y = "Performance Rating")
})
output$performance_by_age <- renderPlot({
ggplot(filtered_data(), aes(x = Age, y = PerformanceRating)) +
geom_point(color = "blue") +
labs(title = "Performance by Age", x = "Age", y = "Performance Rating")
})
output$performance_by_experience <- renderPlot({
ggplot(filtered_data(), aes(x = TotalWorkingYears, y = PerformanceRating)) +
geom_point(color = "green") +
labs(title = "Performance by Experience", x = "Total Working Years",
y = "Performance Rating")
})
output$engagement_by_gender <- renderPlot({
ggplot(filtered_data(), aes(x = Gender, y = JobInvolvement, fill = Gender)) +
geom_boxplot() +
labs(title = "Engagement by Gender", x = "Gender", y = "Engagement Score")
})
output$engagement_by_marital_status <- renderPlot({
ggplot(filtered_data(), aes(x = MaritalStatus, y = JobInvolvement,
fill = MaritalStatus)) +
geom_boxplot() +
labs(title = "Engagement by Marital Status", x = "Marital Status",
y = "Engagement Score")
})
output$engagement_by_job_level <- renderPlot({
ggplot(filtered_data(), aes(x = JobLevel, y = JobInvolvement, fill = JobLevel)) +
geom_boxplot() +
labs(title = "Engagement by Job Level", x = "Job Level", y = "Engagement Score")
})
output$attrition_by_age <- renderPlot({
ggplot(filtered_data(), aes(x = Age, y = Attrition, fill = Attrition)) +
geom_bar(stat = "identity") +
labs(title = "Attrition by Age", x = "Age", y = "Attrition")
})
output$attrition_by_department <- renderPlot({
ggplot(filtered_data(), aes(x = Department, y = Attrition, fill = Department)) +
geom_bar(stat = "identity") +
labs(title = "Attrition by Department", x = "Department", y = "Attrition")
})
output$attrition_by_experience <- renderPlot({
ggplot(filtered_data(), aes(x = TotalWorkingYears, y = Attrition,
fill = Attrition)) +
geom_bar(stat = "identity") +
labs(title = "Attrition by Total Working Years", x = "Total Working Years",
y = "Attrition")
})
}
shinyApp(ui, server)
OUTPUT:
 DASHBOARD ANALYSIS ConclusionIn this article, we discussed the importance of HR management and the role of machine learning in it. We used R and its libraries to evaluate and analyze employee performance. We built multiple graphs to get insights as well as dashboards to understand it better.
|