411 REFERENCE · Wikibooks
Statistics for Sociologists/Chapter 7: Frequency Distributions and Visualizing Data
Reference material by Wikibooks contributors. This retains its source identity and is not 411 news reporting.
Chapter 7: Frequency Distributions and Visualizing Data
Six chapters in, and this is the first one that asks you to actually describe something about the social world using a real statistic. Everything before this was preparation — R, the GSS, variable types, cleaning, recoding. All of it existed to get you to this moment: looking at a distribution of real answers from real people and saying something true about the pattern in front of you.
We start with the simplest possible question you can ask about a variable: what values does it take, and how often does each one show up?
What a Frequency Distribution Is
A frequency distribution is just a systematic count: for every possible value (or range of values) a variable can take, how many respondents fall into it. It sounds almost too basic to deserve a full chapter, and yet a well-constructed frequency distribution is often the single most informative thing you can produce about a variable — more informative, in some cases, than the fancier statistics later chapters will teach you, because it shows you the whole shape of the data at once rather than compressing it into a single number.
Frequency Tables
Base R:
table(gss$HAPPY) # raw counts
prop.table(table(gss$HAPPY)) # proportions
prop.table(table(gss$HAPPY)) * 100 # percentages
dplyr:
library(dplyr)
gss %>%
count(HAPPY) %>%
mutate(proportion = n / sum(n),
percent = proportion * 100)
The dplyr version does more work up front but hands you back a proper data frame — proportions and percentages included as actual columns you can sort, filter, or plot directly — rather than the base R version's separate objects you'd need to combine yourself. Neither is wrong; the dplyr version just anticipates that you'll usually want to do something further with these numbers.
Bar Charts for Categorical Variables
Base R:
barplot(table(gss$RELIG),
main = "Religious Affiliation",
xlab = "Religion", ylab = "Frequency")
alt=A bar chart of religious affiliation created using base R.|center|thumb|800x800px|A simple bar chart of religious affiliation created using base R.
ggplot2:
library(ggplot2)
ggplot(gss, aes(x = RELIG)) +
geom_bar() +
labs(title = "Religious Affiliation", x = "Religion", y = "Frequency")
alt=A simple bar chart of religious affiliation created using the package ggplot2.|center|thumb|800x800px|A simple bar chart of religious affiliation created using the package ggplot2.
Introduction to ggplot2
The ggplot2Wickham, H. (2016). ggplot2: Elegant Graphics for Data Analysis (2nd ed.). Springer-Verlag. syntax looks bizarre the first time you see it, and this book isn't going to pretend otherwise. You build a plot in layers, connected with a + sign that behaves nothing like arithmetic addition — a design choice that made perfect sense to exactly one person, in roughly 2005, and has mildly confused everyone else ever since. And yet it works, and once it clicks, it's a genuinely elegant way to think about visualization: you're not calling one big function with forty arguments, you're stacking simple, composable layers on top of each other.
The core grammar, which the package's name is actually referencing ("grammar of graphics"):
ggplot(data, aes(...)) — start a plot, and declare which variables map to which visual properties (x-axis, y-axis, color, and so on) inside aes() (short for "aesthetics").
geom_*() — add a geometric layer: geom_bar() for bars, geom_histogram() for histograms, geom_point() for scatterplots (Chapter 16), and so on.
labs() — add titles and axis labels.
theme_*() — adjust the plot's overall visual style.
You do not need to master ggplot2 in this chapter, or possibly ever — you need enough of it to produce a clean, readable plot, which the examples in this book will keep demonstrating throughout. Fluency comes from repetition, not from reading one explanation closely.
alt=An annotated ggplot2 code and bar chart linking code to pieces.|center|thumb|800x800px|This image links ggplot2 code to the resulting output in the bar chart.
Histograms for Continuous Variables
A histogram is conceptually a bar chart for continuous data (interval or ratio variables only). Instead of one bar per category, you get one bar per range of values (a "bin"), and the choice of bin width genuinely changes what the plot shows you. Too wide, and you flatten out real structure in the data (a bimodal distribution can disappear entirely into a single wide hump). Too narrow, and you get a jagged, noisy mess that emphasizes sampling variation over the underlying pattern. There's no single correct bin width; try a few and see what reveals the shape most honestly.
Base R:
hist(gss$AGE,
main = "Distribution of Respondent Age",
xlab = "Age")
alt=A histogram of ages using base R.|center|thumb|800x800px|A histogram of ages using base R.
ggplot2:
ggplot(gss, aes(x = AGE)) +
geom_histogram(binwidth = 5) +
labs(title = "Distribution of Respondent Age", x = "Age", y = "Frequency")
alt=A histogram of ages from the 2010 GSS from the R ggplot2 package with binwidth 1.|left|thumb|425x425px|A histogram of ages from the 2010 GSS from the R ggplot2 package with binwidth 1.
alt=A histogram of ages from the 2010 GSS from the R ggplot2 package with binwidth 5.|thumb|425x425px|A histogram of ages from the 2010 GSS from the R ggplot2 package with binwidth 5.
Describing Distributions
Once you can see a distribution, you need vocabulary for describing what you're looking at:
Shape. Is it roughly symmetric (the two halves mirror each other), skewed right or positive skew (a long tail stretching toward higher values, with most cases bunched at the lower end), or skewed left or negative skew (the mirror image — a long tail toward lower values)?
Modality. Does the distribution have one clear peak (unimodal), two (bimodal), or more? A bimodal distribution is often a clue that you're actually looking at two different subgroups blended together — worth investigating rather than just describing.
Outliers. Individual values sitting unusually far from the rest of the distribution — not automatically errors, but always worth a second look.
Skewness in Social Data: The Case of Income
If you want to see real, dramatic right-skew, look no further than income. Most people earn a moderate amount, a shrinking number earn quite a lot, and a very small number earn an amount that makes the x-axis of a histogram nearly useless — everyone else's bar gets flattened into invisibility by the scale required to fit in the tail. This is the mathematical face of wealth inequality, and it's worth sitting with: the distribution's shape is not just a technical detail about which statistic to use (a preview of Chapter 8, where this exact fact determines whether you should trust the mean). It is, in a very real sense, the sociological finding.
alt=A skewed distribution curve with regular people on the left and rich people on the right.|center|thumb|800x800px
The GSS's continuous income measure, CONRINC (respondent income in constant dollars — see Chapter 3), makes this easy to see directly:
ggplot(GSS2010, aes(x = CONINC)) +
geom_histogram(binwidth = 2000) +
labs(title = "Distribution of Respondent Income (CONRINC)",
x = "Income", y = "Frequency")
alt=A histogram illustrated how skewed income is.|center|thumb|800x800px|This histogram illustrates how skewed income is in the 2010 GSS.
Chapter Summary
A frequency distribution counts how often each value of a variable occurs, and it's often the single most informative first look you can take at any variable. Categorical variables are best visualized with bar charts (barplot() in base R, geom_bar() in ggplot2); continuous variables with histograms (hist() or geom_histogram()), where the choice of bin width meaningfully affects what pattern you can see. ggplot2's layered + syntax is unusual on first contact but becomes second nature with repetition, and you only need enough of it to produce clean, readable plots — not mastery. Distributions are described by shape (symmetric, skewed left or right), modality (how many peaks), and outliers. Income is the textbook example of severe right-skew in social data, and that skew isn't a nuisance to work around — it's a genuine finding about inequality that the very next chapter will show you how to properly summarize.
Open Science Corner #355C7D #FFFFFF #F8B195 Save your plots as files with ggsave(), as part of your script, rather than screenshotting whatever appears in RStudio's Plots pane. A screenshot is a dead end — it can't be regenerated, resized, or reproduced if your data changes. A line of code that saves a plot is part of your reproducible pipeline, exactly like everything else in your script. ggsave("happiness_by_income.png", width = 6, height = 4) takes one line and saves you from ever having to explain why your figure looks slightly blurry in the final paper.
Practice Examples
Example 1: Frequency Table for HAPPY
The Research Question: How is happiness distributed across the sample — are most people clustered at one end, or spread out?
The Code (base R):
table(gss$HAPPY)
prop.table(table(gss$HAPPY)) * 100
The Code (dplyr):
library(dplyr)
gss %>%
count(HAPPY) %>%
mutate(percent = round(n / sum(n) * 100, 1))
The Output:
HAPPY n percent
1 538 26.3
2 1184 57.9
3 317 15.5
NA 5 0.2
The Interpretation: Just over half of respondents describe themselves as "pretty happy," the most common response by a wide margin, with "very happy" and "not too happy" splitting the remainder. This is a genuinely common pattern in subjective well-being research: most people report being reasonably content, and a distribution skewed toward the positive end shows up so consistently across different populations and time periods that it's practically a finding in its own right.
Follow-Up Challenge: Compare this distribution to your own prediction before you ran the code. Were you expecting more people to report "very happy," or fewer? Where do you think that intuition came from?
Example 2: Bar Chart of RELIG
The Research Question: What does the religious composition of the sample look like, visually?
The Code (base R):
barplot(table(gss$RELIG),
main = "Religious Affiliation (2010 GSS)",
xlab = "Religion", ylab = "Frequency",
las = 2)
The Code (ggplot2):
library(ggplot2)
ggplot(gss, aes(x = RELIG)) +
geom_bar(fill = "steelblue") +
labs(title = "Religious Affiliation (2010 GSS)", x = "Religion", y = "Frequency") +
theme_minimal()
The Output: A bar chart with one bar per religious category, height proportional to the number of respondents in that category. (See the FIGURE note above — actual bar heights depend on the real 2010 GSS data and should be generated from it rather than estimated.)
The Interpretation: The specific pattern of bar heights tells a story about religious composition that a frequency table alone makes you work harder to see — visual comparison of bar height is nearly instantaneous in a way that scanning a column of numbers isn't. Note the base R version's las = 2 argument, which rotates axis labels vertically; without it, long category names like "Protestant" and "No religion" tend to overlap into an unreadable smear along the x-axis.
Follow-Up Challenge: Reorder the bars from most to least frequent (a "sorted" bar chart) instead of whatever default order the categories happen to be stored in. Does the sorted version make the pattern easier or harder to read?
Example 3: Histogram of AGE
The Research Question: What is the shape of the age distribution in the sample — symmetric, skewed, unimodal, bimodal?
The Code (base R):
hist(gss$AGE, main = "Distribution of Respondent Age", xlab = "Age", breaks = 20)
The Code (ggplot2):
library(ggplot2)
ggplot(gss, aes(x = AGE)) +
geom_histogram(binwidth = 5, fill = "darkolivegreen", color = "white") +
labs(title = "Distribution of Respondent Age", x = "Age", y = "Frequency")
The Output: A histogram with age on the x-axis and respondent counts on the y-axis, roughly moderate in shape with a mild right skew typical of adult-population age distributions (fewer very elderly respondents than middle-aged ones).
The Interpretation: Age distributions in general-population surveys like the GSS are rarely perfectly symmetric — they tend to show a mild right skew, reflecting declining survival and participation rates at the oldest ages relative to the broad middle of adulthood. This is a good habit to build now: before touching a formal statistic, describe the shape you're looking at in plain language. It anchors everything that follows in something you actually observed rather than something you assumed.
Follow-Up Challenge: Try three different values for binwidth (or breaks in base R) — one very small, one very large, one in between. At what point does the histogram stop being informative in each direction?
References