Module 4 of the final project: Cultural Environment Audit
This is the first of five diagnostic modules that build toward your comprehensive leadership profile:
By the end of this module, you will be able to:
Organizational culture is not a soft, fluffy conceptâit is a critical mechanism of social control and motivation that fundamentally shapes:
As a future leader, you must diagnose the existing culture before you can shape it. Understanding what is valued, what is rewarded, and how strongly these norms are enforced will determine your leadership effectiveness and career trajectory.
| Dimension | Definition | Key Questions | Measured By |
|---|---|---|---|
| Cultural Content | How things are done and WHY they are done that way | What values, beliefs, and norms guide behavior? | Perceptions, stories, values, rewards (qualitative themes) |
| Cultural Strength | The degree to which cultural content is SHARED and ENFORCED | How widely held are these values? How consistently enforced? | Consistency across reviews, behavioral enforcement, tenure effects |
To diagnose cultural content, examine:
| Characteristic | Strong Culture | Weak Culture |
|---|---|---|
| Value Consistency | High agreement across reviews on what matters | Divergent or contradictory values mentioned |
| Behavioral Alignment | Clear norms enforced consistently | Norms ambiguous or selectively enforced |
| Tenure Effects | Long-tenured employees echo core values | Values vary by tenure, role, or geography |
| Socialization | Explicit onboarding rituals & language patterns | Sink-or-swim; no clear cultural onboarding |
| Performance Consistency | Predictable outcomes, low variance | Unpredictable outcomes, high variance |
| Adaptability | Resistance to change; homogeneity risk | Easier to change; diversity of perspectives |
Your Task: Diagnose whether the culture is an asset or liability for you as a leader.
Criteria for firm selection: - Company must have 15+ reviews on Glassdoor.com - Ideally a firm you are interested in working for OR currently work at - Should be the same firm you analyzed in Module 3 (Organizational Structure)
Why random? To avoid selection bias (donât cherry-pick positive or negative reviews).
How to randomize: - Use a random number generator
(e.g., sample(1:100, 15) in R) - If Glassdoor shows 100
reviews, generate 15 random numbers between 1-100 - Select the reviews
corresponding to those positions
For each review, provide an ID (you can just number them) and the comment
library(tidyverse)
library(tm)
library(wordcloud)
library(tidytext)
library(ggraph)
library(igraph)
library(sentimentr)
#install.packages('topicmodels')
library(topicmodels)
library(LDAvis)
data<-read.csv("1_MON_Culture_2025FT,v1.csv", header=T)
names(data)## [1] "id"
## [2] "X1061625..How.would.you.describe.the.culture.or.your.experience.thus.far.at.Tepper."
#This variable name changes
my_data_culture <- tibble(id = data[,1],
culture = as.character(data[,2]))
head(my_data_culture)Here you can remove stop words and any other terms that are not relevant to your analysis.
text <- as.character(my_data_culture$culture)
#FUNCTIONS======
clean.text = function(x)
{
# tolower
x = tolower(x)
# remove rt
x = gsub("rt", "", x)
# remove at
x = gsub("@\\w+", "", x)
# remove punctuation
x = gsub("[[:punct:]]", "", x)
# remove numbers
x = gsub("[[:digit:]]", "", x)
# remove links http
x = gsub("http\\w+", "", x)
# remove links https
x = gsub("https\\w+", "", x)
# remove tabs
x = gsub("[ |\t]{2,}", "", x)
# remove blank spaces at the beginning
x = gsub("^ ", "", x)
# remove blank spaces at the end
x = gsub(" $", "", x)
return(x)
}
#Prep data for analysis (calls the function I defined above)
cleanText <- clean.text(text)
#Remove stop words (you can change vector as needed)
remwords <- c("tepper","culture","class", "like", "classmates", "bit", "thus", "want","take", 'experi')#Here we create a function to clean our data and then pass our data to it.
MON.wordcloud <- function(x, lang="english", excludeWords=NULL,
textStemming=T)
{
# Load the text as a corpus
docs <- Corpus(VectorSource(text))
# Convert the text to lower case
docs <- tm_map(docs, content_transformer(tolower))
# Remove numbers
docs <- tm_map(docs, removeNumbers)
# Remove stopwords for the language
docs <- tm_map(docs, removeWords, stopwords(lang))
# Remove punctuations
docs <- tm_map(docs, removePunctuation)
# Eliminate extra white spaces
docs <- tm_map(docs, stripWhitespace)
# Remove your own stopwords
if(!is.null(excludeWords))
docs <- tm_map(docs, removeWords, excludeWords)
# Text stemming
if(textStemming) docs <- tm_map(docs, stemDocument)
# Create term-document matrix
tdm <- TermDocumentMatrix(docs)
m <- as.matrix(tdm)
v <- sort(rowSums(m),decreasing=TRUE)
d <- data.frame(word = names(v),freq=v)
wordcloud(d$word,d$freq, scale=c(3,0.3), max.words=200, random.order=FALSE,
excludeWords = NULL,
rot.per=0.35, colors=brewer.pal(5,"Dark2"))
}
#Call the function with our cleaned data
MON.wordcloud(cleanText, excludeWords=remwords, textStemming=T)Here we classify positive and negative language.
Can you tell whether the statements are in general positive or
negative, and why?
#Simple Sentiment Analysis ====-
text_with_pol <-
cleanText %>%
get_sentences() %>%
sentiment() %>%
mutate(polarity_level = ifelse(sentiment == 0,"Neutral", ifelse(sentiment < 0, "Negative","Positive")))
#Plots sentiment by valence (positive sentiment is above zero and negative sentiment is below zero)
ggplot(text_with_pol, aes(x=sentiment)) +
geom_histogram(color="darkblue", fill="lightblue", binwidth = 0.1)+
geom_vline(xintercept= 0, colour = "red") +
labs(title="Cultural Sentiment Histogram Plot",x="Sentiment", y = "Counts") +
theme_classic()
The co-occurrence graph visualizes the relationships between
words in the statements, with which you can identify clusters or groups
of related words or terms. Can you tell which pairs of words co-occur
the most and what does it tells you about the statements?
set.seed(1234)
data_culture_word_pairs %>%
filter(n >= 4) %>%
graph_from_data_frame() %>%
ggraph(layout = "fr") +
geom_edge_link(aes(edge_alpha = n, edge_width = n), edge_colour = "royalblue") +
geom_node_point(size = 5) +
geom_node_text(aes(label = name), repel = TRUE,
point.padding = unit(0.2, "lines")) +
theme_void()
set.seed(1234)
data_culture_word_pairs %>%
filter(n >= 6) %>%
graph_from_data_frame() %>%
ggraph(layout = "fr") +
geom_edge_link(aes(edge_alpha = n, edge_width = n), edge_colour = "royalblue") +
geom_node_point(size = 5) +
geom_node_text(aes(label = name), repel = TRUE,
point.padding = unit(0.2, "lines")) +
theme_void()
#### STEP 7: Shared Language Network (filtered @ 4) Here we
can start to look at shared strength of the culture in your cohort.
data_culture_student_pairs_2 <-
data_culture2 %>%
widyr::pairwise_count(id, word, sort = TRUE, upper = FALSE)
data_culture_student_pairs_2 %>%
filter(n >= 4) %>%
graph_from_data_frame() %>%
ggraph(layout = "fr") +
geom_edge_link(aes(edge_alpha = n, edge_width = n), edge_colour = "royalblue") +
geom_node_point(size = 5) +
geom_node_text(aes(label = name), repel = TRUE,
point.padding = unit(0.2, "lines")) +
theme_void()
Your culture analysis does NOT stand aloneâit must connect to:
Your task is not to fit into the culture you diagnosed. Your task is to: 1. Understand what is valued, rewarded, and enforced 2. Leverage cultural elements that amplify your leadership strengths 3. Shape cultural elements that constrain your impactâgradually, strategically, authentically
Leadership is not about adapting to culture. Leadership is about architecting culture.
Tutorial created by Prof. Brandy Aven, PhD
Carnegie Mellon University | Tepper School of Business
Course: People Analytics & Strategic Leadership