library(corrplot)
library(ellmer)
library(gmodels)
library(matrixStats)
library(tidyverse)
set.seed(123)
# Location of the data files. Adjust this path if you keep the data
# files in a different directory.
DATA_DIR <- '../data'Chapter 1: Exploratory Data Analysis
Exploratory Data Analysis
Data Dictionaries and Catalogs
system_prompt <- "
Improve the attached data dictionary and return it in YAML format. In addition to
the description of features, provide name, description, source, and
size of the dataset.
For each feature, provide the following information:
- feature name
- readable variable name (if required)
- definition of the variable
- data type
- measurement units
- allowed values (for categorical or nominal features, but only if you are sure)
"
data_dictionary <- "
name: ebay Auctions
description: >
The dataset eBayAuctions.csv contains information on 1972 auctions that
transacted on eBay.com during May-June 2004.
source: Copyright 2016 Galit Shmueli and Peter Bruce
size:
observations: 1972
features: 8
features:
Category: Category of the auctioned item
currency: \"US: US dollar, GBP: English pound, EUR: Euro\"
sellerRating: >
a rating by eBay, as a function of the number of \"good\" and \"bad\"
transactions the seller had on eBay
Duration: Number of days the auction lasted (set by seller at auction start)
endDay: Day of week that the auction closed
ClosePrice: Price item sold at (converted into USD)
OpenPrice: Initial price set by the seller (converted into USD)
Competitive?: whether the auction had a single bid (0) or more (1)
"
message <- paste(c(
"Here is the data dictionary in YAML format:",
data_dictionary,
"First ten lines of the dataset in CSV format:",
read_csv(file.path(DATA_DIR, "eBayAuctions.csv.gz"), show_col_types = FALSE) %>%
sample_n(10) %>%
format_delim(delim = ",", na = "")
), collapse = "\n")
chat <- chat_openai(system_prompt, model = "gpt-4o-mini")
response <- chat$chat(message)Here’s an improved version of your data dictionary in YAML format:
```yaml
name: ebay Auctions
description: >
The dataset eBayAuctions.csv contains information on 1972 auctions that
were transacted on eBay.com during May-June 2004.
source: Copyright 2016 Galit Shmueli and Peter Bruce
size:
observations: 1972
features: 8
features:
- feature_name: Category
readable_variable_name: Auction Category
definition: Category of the auctioned item
data_type: categorical
allowed_values:
- Music/Movie/Game
- Coins/Stamps
- Automotive
- Health/Beauty
- Toys/Hobbies
- Collectibles
- feature_name: currency
readable_variable_name: Currency Type
definition: Currency used for the auction prices
data_type: categorical
allowed_values:
- US
- GBP
- EUR
- feature_name: sellerRating
readable_variable_name: Seller Rating
definition: A rating by eBay based on the number of 'good' and 'bad'
transactions the seller had
data_type: integer
measurement_units: rating scale
- feature_name: Duration
readable_variable_name: Auction Duration
definition: Number of days the auction lasted (set by seller at auction
start)
data_type: integer
measurement_units: days
- feature_name: endDay
readable_variable_name: End Day of Auction
definition: Day of the week that the auction closed
data_type: categorical
allowed_values:
- Mon
- Tue
- Wed
- Thu
- Fri
- Sat
- Sun
- feature_name: ClosePrice
readable_variable_name: Closing Price
definition: Price at which the item sold (converted into USD)
data_type: float
measurement_units: USD
- feature_name: OpenPrice
readable_variable_name: Opening Price
definition: Initial price set by the seller (converted into USD)
data_type: float
measurement_units: USD
- feature_name: Competitive
readable_variable_name: Competitive Bidding
definition: Indicates whether the auction had a single bid (0) or more (1)
data_type: categorical
allowed_values:
- 0: Single Bid
- 1: Multiple Bids
```
Feel free to let me know if you need any further modifications or additional
information!
Estimates of Location
Example: Location Estimates of Population and Murder Rates
state <- read_csv(file.path(DATA_DIR, "state.csv"), show_col_types = FALSE)
population <- state[["Population"]]
mean(population)[1] 6162876
mean(population, trim = 0.1)[1] 4783697
median(population)[1] 4436370
weighted.mean(state[["Murder.Rate"]], w = state[["Population"]])[1] 4.445834
weightedMedian(state[["Murder.Rate"]], w = state[["Population"]])[1] 4.4
Estimates of Variability
Example: Variability Estimates of State Population
sd(state[["Population"]])[1] 6848235
IQR(state[["Population"]])[1] 4847308
mad(state[["Population"]])[1] 3849870
Exploring the Data Distribution
Percentiles and Boxplots
quantile(state[["Murder.Rate"]], p = c(0.05, 0.25, 0.5, 0.75, 0.95)) 5% 25% 50% 75% 95%
1.600 2.425 4.000 5.550 6.510
ggplot(state, aes(y = Population / 1000000)) +
geom_boxplot(staplewidth = 0.25) +
labs(y = "Population (millions)") +
scale_x_discrete(labels = NULL, breaks = NULL)
Frequency Tables and Histograms
breaks <- seq(
from = min(state[["Population"]]),
to = max(state[["Population"]]), length = 11)
state %>%
mutate(BinRange = cut(Population, breaks = breaks,
right = TRUE, include.lowest = TRUE)) %>%
count(BinRange, .drop = FALSE)# A tibble: 10 × 2
BinRange n
<fct> <int>
1 [5.64e+05,4.23e+06] 24
2 (4.23e+06,7.9e+06] 14
3 (7.9e+06,1.16e+07] 6
4 (1.16e+07,1.52e+07] 2
5 (1.52e+07,1.89e+07] 1
6 (1.89e+07,2.26e+07] 1
7 (2.26e+07,2.62e+07] 1
8 (2.62e+07,2.99e+07] 0
9 (2.99e+07,3.36e+07] 0
10 (3.36e+07,3.73e+07] 1
ggplot(state, aes(x = Population)) +
geom_histogram(breaks = breaks, fill = "grey", color = "black") +
labs(y = "Frequency")
Density Plots and Estimates
ggplot(state, aes(x = Murder.Rate)) +
geom_histogram(aes(y = after_stat(density)), bins = 12, fill = "grey",
color = "black") +
geom_density() +
labs(x = "Murder Rate (per 100,000)", y = "Density")
Exploring Binary and Categorical Data
dfw <- read_csv(file.path(DATA_DIR, "dfw_airline.csv"), show_col_types = FALSE) %>%
pivot_longer(everything())
ggplot(dfw, aes(x = name, y = value)) +
geom_col(color = "black", fill = "grey") +
labs(x = "Cause of delay", y = "Count")
Correlation
sp500_px <- read_csv(file.path(DATA_DIR, "sp500_data.csv.gz"), show_col_types = FALSE)
sp500_sym <- read_csv(file.path(DATA_DIR, "sp500_sectors.csv"), show_col_types = FALSE)
etf_symbols <- sp500_sym %>%
filter(sector == "etf") %>%
pull(symbol)
etfs <- sp500_px %>%
filter(Date > "2012-07-01") %>%
select(all_of(etf_symbols))
corrplot(cor(etfs), method = "ellipse")
corrplot(cor(etfs), method = "ellipse")
Scatterplots
ggplot(sp500_px %>% filter(Date > "2012-07-01"), aes(x = T, y = VZ)) +
geom_point(shape = 1) +
labs(x = "ATT (T)", y = "Verizon (VZ)")
Exploring Two or More Variables
Hexagonal Binning and Contours pass:[<span class#“keep-together”>(Plotting Numeric-Versus-Numeric Data)]
kc_tax <- read_csv(file.path(DATA_DIR, "kc_tax.csv.gz"), show_col_types = FALSE)
kc_tax0 <- kc_tax %>%
filter(TaxAssessedValue < 750000,
SqFtTotLiving > 100,
SqFtTotLiving < 3500)
nrow(kc_tax0)[1] 432693
ggplot(kc_tax0, (aes(x = SqFtTotLiving, y = TaxAssessedValue))) +
geom_hex(color = "white") +
scale_fill_gradient(low = "white", high = "black") +
labs(x = "Finished Square Feet", y = "Tax-Assessed Value")
ggplot(kc_tax0, aes(SqFtTotLiving, TaxAssessedValue)) +
geom_point(shape = 1, alpha = 0.02) +
geom_density2d(color = "white") +
labs(x = "Finished Square Feet", y = "Tax-Assessed Value")
Two Categorical Variables
lc_loans <- read_csv(file.path(DATA_DIR, "lc_loans.csv"), show_col_types = FALSE)
x_tab <- CrossTable(lc_loans$grade, lc_loans$status,
prop.c = FALSE, prop.chisq = FALSE, prop.t = FALSE)
Cell Contents
|-------------------------|
| N |
| N / Row Total |
|-------------------------|
Total Observations in Table: 450961
| lc_loans$status
lc_loans$grade | Charged Off | Current | Fully Paid | Late | Row Total |
---------------|-------------|-------------|-------------|-------------|-------------|
A | 1562 | 50051 | 20408 | 469 | 72490 |
| 0.022 | 0.690 | 0.282 | 0.006 | 0.161 |
---------------|-------------|-------------|-------------|-------------|-------------|
B | 5302 | 93852 | 31160 | 2056 | 132370 |
| 0.040 | 0.709 | 0.235 | 0.016 | 0.294 |
---------------|-------------|-------------|-------------|-------------|-------------|
C | 6023 | 88928 | 23147 | 2777 | 120875 |
| 0.050 | 0.736 | 0.191 | 0.023 | 0.268 |
---------------|-------------|-------------|-------------|-------------|-------------|
D | 5007 | 53281 | 13681 | 2308 | 74277 |
| 0.067 | 0.717 | 0.184 | 0.031 | 0.165 |
---------------|-------------|-------------|-------------|-------------|-------------|
E | 2842 | 24639 | 5949 | 1374 | 34804 |
| 0.082 | 0.708 | 0.171 | 0.039 | 0.077 |
---------------|-------------|-------------|-------------|-------------|-------------|
F | 1526 | 8444 | 2328 | 606 | 12904 |
| 0.118 | 0.654 | 0.180 | 0.047 | 0.029 |
---------------|-------------|-------------|-------------|-------------|-------------|
G | 409 | 1990 | 643 | 199 | 3241 |
| 0.126 | 0.614 | 0.198 | 0.061 | 0.007 |
---------------|-------------|-------------|-------------|-------------|-------------|
Column Total | 22671 | 321185 | 97316 | 9789 | 450961 |
---------------|-------------|-------------|-------------|-------------|-------------|
# Alternative to create crosstable using tidyverse
crosstab <- lc_loans %>%
group_by(status, grade) %>%
count() %>% # adds column n with the size of each group
pivot_wider(id_cols = grade, names_from = status, values_from = n)
crosstab# A tibble: 7 × 5
# Groups: grade [7]
grade `Charged Off` Current `Fully Paid` Late
<chr> <int> <int> <int> <int>
1 A 1562 50051 20408 469
2 B 5302 93852 31160 2056
3 C 6023 88928 23147 2777
4 D 5007 53281 13681 2308
5 E 2842 24639 5949 1374
6 F 1526 8444 2328 606
7 G 409 1990 643 199
Categorical and Numeric Data
airline_stats <- read_csv(file.path(DATA_DIR, "airline_stats.csv"), show_col_types = FALSE) %>%
mutate(
airline = factor(airline,
levels = c("Alaska", "American", "JetBlue", "Delta", "United",
"Southwest"))
) %>%
drop_na()
ggplot(airline_stats, aes(x = airline, y = pct_carrier_delay)) +
geom_boxplot() +
coord_cartesian(ylim = c(0, 50)) +
labs(x = "Airline", y = "Daily % of Delayed Flights")
ggplot(data = airline_stats, aes(airline, pct_carrier_delay)) +
geom_violin() +
coord_cartesian(ylim = c(0, 50)) +
labs(x = "", y = "Daily % of Delayed Flights")
Visualizing Multiple Variables
kc_subset <- kc_tax0 %>%
filter(ZipCode %in% c(98188, 98105, 98108, 98126))
ggplot(kc_subset, aes(x = SqFtTotLiving, y = TaxAssessedValue)) +
geom_hex(color = "white") +
scale_fill_gradient(low = "white", high = "blue") +
labs(x = "Finished Square Feet", y = "Tax-Assessed Value") +
facet_wrap("ZipCode")
Supplementary Material
Table 1-2. A few rows of the data.frame state of population and murder rate by state
state %>%
mutate(
Population = formatC(Population, format = "d", digits = 0, big.mark = ","),
) %>%
head(8)# A tibble: 8 × 4
State Population Murder.Rate Abbreviation
<chr> <chr> <dbl> <chr>
1 Alabama 4,779,736 5.7 AL
2 Alaska 710,231 5.6 AK
3 Arizona 6,392,017 4.7 AZ
4 Arkansas 2,915,918 5.6 AR
5 California 37,253,956 4.4 CA
6 Colorado 5,029,196 2.8 CO
7 Connecticut 3,574,097 2.4 CT
8 Delaware 897,934 5.8 DE
Table 1-4. Percentiles of murder rate by state
Table 1-5. A frequency table of population by state
Table 1-6. Percentage of delays by cause at Dallas/Fort Worth Airport
Table 1-7. Correlation between telecommunication stock returns
Figure 1-6. Correlation between ETF returns (Python version)
Figure 1-6. Correlation between ETF returns using a heat map (R version)
sp500_px <- read_csv(file.path(DATA_DIR, "sp500_data.csv.gz"), show_col_types = FALSE)
sp500_sym <- read_csv(file.path(DATA_DIR, "sp500_sectors.csv"), show_col_types = FALSE)
etf_symbols <- sp500_sym %>%
filter(sector == "etf") %>%
pull(symbol)
etfs <- sp500_px %>%
filter(Date > "2012-07-01") %>%
select(all_of(etf_symbols))
correlation_matrix <- cor(etfs) %>%
as_tibble() %>%
mutate(Var1 = colnames(.)) %>%
pivot_longer(-Var1, names_to = "Var2", values_to = "value")
ggplot(correlation_matrix, aes(x = Var1, y = Var2)) +
geom_tile(aes(fill = value)) +
scale_fill_gradient2(limits = c(-1, 1))