library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.2.1 ✔ readr 2.2.0
## ✔ forcats 1.0.1 ✔ stringr 1.6.0
## ✔ ggplot2 4.0.3 ✔ tibble 3.3.1
## ✔ lubridate 1.9.5 ✔ tidyr 1.3.2
## ✔ purrr 1.2.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(nycflights13)
ggplot(diamonds, aes(x = x)) +
geom_histogram(binwidth = 0.5)
ggplot(diamonds, aes(x = y)) +
geom_histogram(binwidth = 0.5)
ggplot(diamonds, aes(x = z)) +
geom_histogram(binwidth = 0.5)
The distributions of x and y are similar because both represent the horizontal dimensions of a diamond. The z variable represents depth and generally has smaller measurements.
Most diamonds are concentrated within a relatively small range, but there are some unusual values, including zeros and extremely large measurements. These could indicate data entry errors.
When determining length, width, and depth, I would consider the longest horizontal dimension the length, the other horizontal dimension the width, and the vertical measurement the depth. In this dataset, x is labeled length, y is width, and z is depth.
ggplot(diamonds, aes(x = price)) +
geom_histogram(binwidth = 500)
ggplot(diamonds, aes(x = price)) +
geom_histogram(binwidth = 100)
ggplot(diamonds, aes(x = price)) +
geom_histogram(binwidth = 10) +
coord_cartesian(xlim = c(1000, 2000))
The distribution of diamond prices is right-skewed, meaning there are more lower-priced diamonds than expensive ones.
Something unusual becomes visible when decreasing the bin width: there is a noticeable dip in the number of diamonds priced around $1,500.
Changing the bin width makes it easier to identify patterns that might not be visible when using larger bins.
diamonds %>%
filter(carat == 0.99 | carat == 1) %>%
count(carat)
## # A tibble: 2 × 2
## carat n
## <dbl> <int>
## 1 0.99 23
## 2 1 1558
There are only 23 diamonds weighing 0.99 carats compared to 1,558 diamonds weighing exactly 1 carat.
This difference may occur because 1-carat diamonds are more desirable and can sell for higher prices. Diamond cutters may try to preserve enough weight to reach the 1-carat mark instead of producing diamonds just below it.
The difference might also reflect how diamonds are selected for the dataset.
ggplot(diamonds, aes(x = price)) +
geom_histogram(binwidth = 500) +
coord_cartesian(xlim = c(2000, 8000))
ggplot(diamonds, aes(x = price)) +
geom_histogram(binwidth = 500) +
xlim(2000, 8000)
## Warning: Removed 31808 rows containing non-finite outside the scale range
## (`stat_bin()`).
## Warning: Removed 2 rows containing missing values or values outside the scale range
## (`geom_bar()`).
ggplot(diamonds, aes(x = price)) +
geom_histogram(binwidth = 500) +
coord_cartesian(ylim = c(0, 1000))
coord_cartesian() zooms in on a selected part of a graph without removing observations from the underlying calculation.
In contrast, xlim() removes data outside the specified x-axis limits before the histogram is calculated. This can change the appearance and counts of the bars.
If binwidth is not specified, geom_histogram() uses 30 bins by default, and their widths may change when the data range changes.
When zooming so that only half a bar is visible, coord_cartesian() clips the bar visually. Using ylim() instead can remove the entire bar if its calculated height falls outside the specified range.
The main difference: coord_cartesian() changes what is visible, while xlim() and ylim() can affect the data displayed and the calculated histogram.
#10.4.1
data <- tibble(
number = c(1, 2, 3, 4, 5, NA),
category = c("A", "B", "A", "B", "A", NA)
)
ggplot(data, aes(x = number)) +
geom_histogram(binwidth = 1)
## Warning: Removed 1 row containing non-finite outside the scale range
## (`stat_bin()`).
ggplot(data, aes(x = category)) +
geom_bar()
In a histogram, missing values are excluded because they cannot be placed within a numerical interval. R may display a warning about the missing observations.
In a bar chart, missing values are usually displayed as their own category because bar charts represent categorical data.
The difference occurs because histograms are designed for numerical variables, while bar charts are used to show counts of categories.
numbers <- c(10, 20, 30, NA)
mean(numbers)
## [1] NA
mean(numbers, na.rm = TRUE)
## [1] 20
sum(numbers)
## [1] NA
sum(numbers, na.rm = TRUE)
## [1] 60
The argument na.rm = TRUE tells R to ignore missing values when performing calculations.
Without it, mean() and sum() return NA when missing values are present. When na.rm = TRUE is included, R calculates the result using only the available numbers.
flights %>%
mutate(
cancelled = is.na(dep_time),
sched_hour = sched_dep_time %/% 100,
sched_min = sched_dep_time %% 100,
scheduled_dep_time = sched_hour + sched_min / 60
) %>%
ggplot(aes(x = scheduled_dep_time, color = cancelled)) +
geom_freqpoly(binwidth = 1/4)
The code creates a variable called cancelled that identifies whether the actual departure time is missing.
It also converts the scheduled departure time from the HHMM format into decimal hours so that departure times can be plotted correctly.
flights %>%
mutate(
cancelled = is.na(dep_time),
sched_hour = sched_dep_time %/% 100,
sched_min = sched_dep_time %% 100,
scheduled_dep_time = sched_hour + sched_min / 60
) %>%
ggplot(aes(x = scheduled_dep_time, color = cancelled)) +
geom_freqpoly(binwidth = 1/4) +
facet_wrap(~cancelled)
flights %>%
mutate(
cancelled = is.na(dep_time),
sched_hour = sched_dep_time %/% 100,
sched_min = sched_dep_time %% 100,
scheduled_dep_time = sched_hour + sched_min / 60
) %>%
ggplot(aes(x = scheduled_dep_time, color = cancelled)) +
geom_freqpoly(binwidth = 1/4) +
facet_wrap(~cancelled, scales = "free_y")
The frequency plot shows that there are significantly more non-cancelled flights than cancelled flights.
Using facet_wrap() separates the two groups into individual panels, making their distributions easier to examine.
When the scales are fixed, the cancelled flights appear much smaller because both panels share the same y-axis range.
Changing the argument to scales = “free_y” allows each panel to have its own y-axis scale. This makes the patterns of cancelled flights easier to see.