This worksheet introduces exploratory data analysis (EDA) in RStudio. First, you will follow a complete example using one synthetic brigade. Then you will choose your own brigade and variables and repeat the analysis.
The data are synthetic. The records describe fictional Soldiers and are for classroom practice only.
This worksheet uses four packages:
rmarkdown creates the finished HTML report.readr imports the CSV file.dplyr filters and summarizes data.ggplot2 creates graphs.Run the next chunk only if the packages are not already installed. Installation normally needs to happen only once on a computer.
required_packages <- c("rmarkdown", "readr", "dplyr", "ggplot2")
missing_packages <- required_packages[
!required_packages %in% rownames(installed.packages())
]
if (length(missing_packages) > 0) {
install.packages(missing_packages)
} else {
message("All required packages are already installed.")
}
Run this chunk each time you open RStudio. The rmarkdown
package does not need a library() line because RStudio uses
it when you click Knit.
library(readr)
library(dplyr)
library(ggplot2)
Use the green Run button in the upper-right corner of a code chunk to run that chunk. You can also place your cursor inside a chunk and press Ctrl+Shift+Enter.
R ignores any text after a # in a code chunk. These
comments explain what the code does.
# R can perform calculations.
4 * 5
## [1] 20
# <- stores a value with a name.
example_scores <- c(28, 31, 34, 35, 37)
# A function performs an action.
mean(example_scores)
## [1] 33
max(example_scores)
## [1] 37
Keep army_brigades_synthetic.csv in the same folder as
this R Markdown file.
csv_name <- "army_brigades_synthetic.csv"
data_file <- csv_name
# If RStudio is working from another folder, look beside the open Rmd.
if (!file.exists(data_file) &&
requireNamespace("rstudioapi", quietly = TRUE) &&
rstudioapi::isAvailable()) {
rmd_path <- rstudioapi::getSourceEditorContext()$path
if (nzchar(rmd_path)) {
data_file <- file.path(dirname(rmd_path), csv_name)
}
}
if (!file.exists(data_file)) {
stop(
"Could not find army_brigades_synthetic.csv. ",
"Place the CSV in the same folder as this R Markdown file."
)
}
army_data <- readr::read_csv(data_file, show_col_types = FALSE)
If this chunk produces a “file not found” error, move the CSV into
the same folder as the .Rmd file and run the chunk
again.
A row is one observation. A column is one variable.
# Display the first six rows.
head(army_data)
## # A tibble: 6 × 46
## uic_hierarchy CorpsName DivisionName BrigadeName brigade battalion company
## <chr> <chr> <chr> <chr> <chr> <chr> <chr>
## 1 W9LG6N;W55434;W1… III ARMO… 1ST INFANTR… 6TH BCT 1S… 6BCT 2-63 IN F CO 2…
## 2 W9LG6N;W55434;WP… III ARMO… 1ST INFANTR… 3RD BCT 1S… 3BCT 4-8 FA E CO 4…
## 3 W9LG6N;W55434;W1… III ARMO… 1ST INFANTR… 2ND BCT 1S… 2BCT 5-82 CAV C CO 5…
## 4 W9LG6N;W55434;W1… III ARMO… 1ST INFANTR… 6TH BCT 1S… 6BCT 2-63 IN A CO 2…
## 5 W9LG6N;W55434;WR… III ARMO… 1ST INFANTR… 4TH BCT 1S… 4BCT 4-26 FA B CO 4…
## 6 W9LG6N;W55434;W1… III ARMO… 1ST INFANTR… 2ND BCT 1S… 2BCT 5-82 CAV F CO 5…
## # ℹ 39 more variables: sex <chr>, age <dbl>, age_bracket <chr>,
## # time_in_active_service_years <dbl>, skill_level <chr>,
## # primary_specialty_code <chr>, asi_and_sqi <chr>, languages_cleaned <chr>,
## # height <dbl>, weight <dbl>, body_comp_pass <lgl>, body_fat_percent <dbl>,
## # aft_date <date>, aft_pass <lgl>, aft_result_summary <chr>,
## # aft_score_total <dbl>, aft_score_plank <dbl>, aft_score_push_up <dbl>,
## # aft_score_sprint_drag_carry <dbl>, aft_score_2mi_run <dbl>, …
# Find the number of rows and columns.
dim(army_data)
## [1] 34472 46
# List all column names.
names(army_data)
## [1] "uic_hierarchy" "CorpsName"
## [3] "DivisionName" "BrigadeName"
## [5] "brigade" "battalion"
## [7] "company" "sex"
## [9] "age" "age_bracket"
## [11] "time_in_active_service_years" "skill_level"
## [13] "primary_specialty_code" "asi_and_sqi"
## [15] "languages_cleaned" "height"
## [17] "weight" "body_comp_pass"
## [19] "body_fat_percent" "aft_date"
## [21] "aft_pass" "aft_result_summary"
## [23] "aft_score_total" "aft_score_plank"
## [25] "aft_score_push_up" "aft_score_sprint_drag_carry"
## [27] "aft_score_2mi_run" "aft_score_alt_aerobic"
## [29] "aft_raw_plank" "aft_raw_plank_seconds"
## [31] "aft_raw_deadlift" "aft_deadlift_score"
## [33] "aft_raw_push_up" "aft_raw_sprint_drag_carry"
## [35] "aft_raw_sprint_drag_carry_seconds" "aft_raw_2mi_run"
## [37] "aft_raw_2mi_run_seconds" "aft_raw_alt_aerobic"
## [39] "m4" "pistol"
## [41] "m249" "m320"
## [43] "shotgun" "anti_tank"
## [45] "sniper" "smg"
The dataset contains both quantitative and categorical variables.
m4, height, or
aft_score_total.brigade, sex, or
age_bracket.Use the next two commands when deciding which variables to study later.
# Quantitative variables
names(army_data)[sapply(army_data, is.numeric)]
## [1] "age" "time_in_active_service_years"
## [3] "height" "weight"
## [5] "body_fat_percent" "aft_score_total"
## [7] "aft_score_plank" "aft_score_push_up"
## [9] "aft_score_sprint_drag_carry" "aft_score_2mi_run"
## [11] "aft_score_alt_aerobic" "aft_raw_plank_seconds"
## [13] "aft_raw_deadlift" "aft_deadlift_score"
## [15] "aft_raw_push_up" "aft_raw_sprint_drag_carry_seconds"
## [17] "aft_raw_2mi_run_seconds" "m4"
## [19] "pistol" "m320"
## [21] "shotgun" "anti_tank"
## [23] "sniper"
# Categorical variables
names(army_data)[!sapply(army_data, is.numeric)]
## [1] "uic_hierarchy" "CorpsName"
## [3] "DivisionName" "BrigadeName"
## [5] "brigade" "battalion"
## [7] "company" "sex"
## [9] "age_bracket" "skill_level"
## [11] "primary_specialty_code" "asi_and_sqi"
## [13] "languages_cleaned" "body_comp_pass"
## [15] "aft_date" "aft_pass"
## [17] "aft_result_summary" "aft_raw_plank"
## [19] "aft_raw_sprint_drag_carry" "aft_raw_2mi_run"
## [21] "aft_raw_alt_aerobic" "m249"
## [23] "smg"
The example uses the synthetic 1BCT records. The primary
variable is m4, and the grouping variable is
age_bracket.
The filter() function keeps rows that meet a condition.
The == symbol means “is equal to.”
example_data <- army_data %>%
filter(brigade == "1BCT")
# Confirm that the filter returned observations.
nrow(example_data)
## [1] 4301
The %>% symbol is called a pipe.
Read it as “and then.” The code starts with army_data and
then filters it to 1BCT.
R displays a missing value as NA. Missing values are not
zeroes.
# Count missing M4 scores.
sum(is.na(example_data$m4))
## [1] 267
# Count available M4 scores.
sum(!is.na(example_data$m4))
## [1] 4034
The $ symbol selects one column from a dataset.
Therefore, example_data$m4 means “the m4
column in example_data.”
The mean and median describe the center of a distribution. Standard
deviation and IQR describe its spread. The option
na.rm = TRUE tells R to ignore missing values for that
calculation.
example_data %>%
summarize(
observations = sum(!is.na(m4)),
mean = mean(m4, na.rm = TRUE),
median = median(m4, na.rm = TRUE),
standard_deviation = sd(m4, na.rm = TRUE),
iqr = IQR(m4, na.rm = TRUE),
minimum = min(m4, na.rm = TRUE),
maximum = max(m4, na.rm = TRUE)
)
## # A tibble: 1 × 7
## observations mean median standard_deviation iqr minimum maximum
## <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 4034 32.1 33 5.47 10 23 40
The mean is sensitive to unusually high or low observations. The median is more resistant to those values.
Think about it: Are the mean and median similar? What does that suggest about the center of the M4 score distribution?
A histogram shows the shape of one quantitative variable. Each bar counts observations in an interval.
example_data %>%
filter(!is.na(m4)) %>%
ggplot(aes(x = m4)) +
geom_histogram(
bins = 10,
fill = "steelblue",
color = "white"
) +
labs(
title = "Distribution of M4 Scores in 1BCT",
x = "M4 Score",
y = "Number of Soldiers"
) +
theme_minimal()
When describing a histogram, discuss its shape, center, spread, and unusual features.
A boxplot displays the median, the middle 50% of the observations, and possible outliers.
example_data %>%
filter(!is.na(m4)) %>%
ggplot(aes(x = m4)) +
geom_boxplot(
fill = "darkseagreen3",
color = "gray25"
) +
labs(
title = "Boxplot of M4 Scores in 1BCT",
x = "M4 Score",
y = NULL
) +
theme_minimal()
Points beyond the whiskers are possible outliers. A possible outlier deserves investigation; it is not automatically an error.
The group_by() function separates the observations into
categories before calculating statistics.
example_data %>%
filter(!is.na(m4), !is.na(age_bracket)) %>%
group_by(age_bracket) %>%
summarize(
observations = n(),
mean = mean(m4),
median = median(m4),
standard_deviation = sd(m4),
.groups = "drop"
)
## # A tibble: 7 × 5
## age_bracket observations mean median standard_deviation
## <chr> <int> <dbl> <dbl> <dbl>
## 1 16-20 186 27.5 26 4.52
## 2 20-25 1370 30.0 30 5.21
## 3 25-30 1220 32.4 33 5.23
## 4 30-35 682 33.9 35 5.01
## 5 35-40 337 34.9 36 4.58
## 6 40-45 198 35.9 37 4.16
## 7 45+ 41 37.1 38 3.38
Side-by-side boxplots make visual comparisons easier.
example_data %>%
filter(!is.na(m4), !is.na(age_bracket)) %>%
ggplot(aes(x = age_bracket, y = m4)) +
geom_boxplot(fill = "tan2") +
labs(
title = "M4 Scores by Age Bracket in 1BCT",
x = "Age Bracket",
y = "M4 Score"
) +
theme_minimal()
Think about it: Which group has the highest median? Which group has the greatest spread? Are the group sizes similar?
A scatterplot shows the relationship between two quantitative variables. Look for direction, strength, form, and unusual observations.
example_data %>%
filter(!is.na(height), !is.na(weight), height < 100) %>%
ggplot(aes(x = height, y = weight)) +
geom_point(alpha = 0.5, color = "steelblue4") +
labs(
title = "Height and Weight in 1BCT",
subtitle = "The plot excludes heights of 100 inches or more",
x = "Height (inches)",
y = "Weight (pounds)"
) +
theme_minimal()
The height rule is shown in the code and subtitle. Never remove suspicious observations silently.
EDA includes looking for missing, impossible, or inconsistent values. The following checks flag known issues in the synthetic CSV without changing the data.
# Heights recorded as 100 inches or more
army_data %>%
filter(height >= 100) %>%
select(brigade, battalion, height, weight)
## # A tibble: 12 × 4
## brigade battalion height weight
## <chr> <chr> <dbl> <dbl>
## 1 6BCT 4-32 FA 169 197
## 2 5BCT 2-26 AR 168 185
## 3 1BCT 5-16 CAV 183 227
## 4 5BCT 1-41 AR 182 193
## 5 1BCT 4-5 FA 182 187
## 6 DSB 3-32 BSB 185 200
## 7 1BCT 5-16 CAV 175 141
## 8 1BCT 3-8 IN 187 225
## 9 1BCT 5-16 CAV 161 175
## 10 1BCT 5-16 CAV 182 171
## 11 6BCT 1-16 IN 178 212
## 12 4BCT 2-41 IN 165 220
# Body-fat percentages below zero
army_data %>%
filter(body_fat_percent < 0) %>%
select(brigade, battalion, body_fat_percent)
## # A tibble: 42 × 3
## brigade battalion body_fat_percent
## <chr> <chr> <dbl>
## 1 4BCT 2-41 IN -1
## 2 1MEB 1-16 EN -2
## 3 2BCT 4-77 FA -5
## 4 1BCT 5-16 CAV -3
## 5 CAB 2-16 AV -1
## 6 5BCT 2-26 AR -5
## 7 6BCT HHB 6BCT -4
## 8 CAB HHB CAB -4
## 9 1BCT 5-16 CAV -4
## 10 3BCT 5-26 CAV -2
## # ℹ 32 more rows
An unusual value is not automatically wrong. State what you found and explain any decision to keep or exclude it from a particular calculation or graph.
You will now repeat the EDA process using your own choices. Complete each step in order.
Run this code to see the available brigade names and their sample sizes.
army_data %>%
count(brigade) %>%
arrange(brigade)
## # A tibble: 10 × 2
## brigade n
## <chr> <int>
## 1 1BCT 4301
## 2 1MEB 1599
## 3 2BCT 4100
## 4 3BCT 4399
## 5 4BCT 4251
## 6 5BCT 4052
## 7 6BCT 4201
## 8 CAB 2700
## 9 DIVARTY 2968
## 10 DSB 1901
You need:
Change the four selections in the next chunk. The first choice is inside quotation marks. The three column names are not inside quotation marks.
# CHANGE this brigade.
my_brigade <- "CAB"
# CHANGE m4, aft_score_total, and age_bracket to your variables.
# The new names on the left stay the same.
my_data <- army_data %>%
filter(brigade == my_brigade) %>%
transmute(
my_variable = time_in_active_service_years,
my_second_variable = aft_score_2mi_run,
my_group = company
)
The transmute() function gives your chosen columns
simple names. The rest of the worksheet uses my_variable,
my_second_variable, and my_group, so you only
need to choose the original columns once.
Run this chunk before continuing.
# This number must be greater than zero.
nrow(my_data)
## [1] 2700
# The first two variables should say num or int.
# The grouping variable should say chr, fct, or logi.
str(my_data)
## tibble [2,700 × 3] (S3: tbl_df/tbl/data.frame)
## $ my_variable : num [1:2700] 1.45 4.54 1.04 9.74 6.89 ...
## $ my_second_variable: num [1:2700] NA 70 60 71 NA 0 97 0 NA 87 ...
## $ my_group : chr [1:2700] "F CO 3-41 AV" "C CO 1-26 AV" "F CO 3-41 AV" "F CO 3-41 AV" ...
if (nrow(my_data) == 0) {
stop("Your brigade name did not match the data. Check its spelling.")
}
if (!is.numeric(my_data$my_variable) ||
!is.numeric(my_data$my_second_variable)) {
stop("Choose quantitative variables for my_variable and my_second_variable.")
}
if (is.numeric(my_data$my_group)) {
stop("Choose a categorical variable for my_group.")
}
Record your choices in your own words:
my_data %>%
summarize(
primary_missing = sum(is.na(my_variable)),
second_missing = sum(is.na(my_second_variable)),
group_missing = sum(is.na(my_group))
)
## # A tibble: 1 × 3
## primary_missing second_missing group_missing
## <int> <int> <int>
## 1 7 486 0
Write 1–2 sentences: Which selected variable has the most missing values? How might missing observations affect your analysis?
My second variable, AFT 2 mile run score, has the most missing values. It is due to the fact that not every soldier conducted the 2 mile run, and instead they did the alternate aerobic test. This will affect my analysis since I am evaluating which company and soldiers with certain years of active service have good AFT 2 mile run time and I still have to work with 486 missing values.
my_data %>%
summarize(
observations = sum(!is.na(my_variable)),
mean = mean(my_variable, na.rm = TRUE),
median = median(my_variable, na.rm = TRUE),
standard_deviation = sd(my_variable, na.rm = TRUE),
iqr = IQR(my_variable, na.rm = TRUE),
minimum = min(my_variable, na.rm = TRUE),
maximum = max(my_variable, na.rm = TRUE)
)
## # A tibble: 1 × 7
## observations mean median standard_deviation iqr minimum maximum
## <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 2693 4.96 3.43 4.28 5.08 -2.83 20.7
Write 2–3 sentences: What is a typical value? How much variability is present? Are the mean and median similar?
The typical value for for the time in active service years is 4.96 years and the variability is 4.27 years more or less than 4.96 years. The mean and median are not similar and it could be due to the distribution being skewed or due to outliers. The outliers will greatly affect the the mean and not the median.
my_data %>%
filter(!is.na(my_variable)) %>%
ggplot(aes(x = my_variable)) +
geom_histogram(
bins = 12,
fill = "steelblue",
color = "white"
) +
labs(
title = paste("Distribution of My Variable in", my_brigade),
x = "My Primary Variable",
y = "Number of Soldiers"
) +
theme_minimal()
Write 2–3 sentences: Describe the distribution’s shape, center, spread, and unusual features.
The distribution is normal but it is right skewed. The mean is greater than the median, which is why the primary variable is being pulled to the right. Most of the values are between 1-5 years, with typical value between 3-4 years. The spread is large and a few negative values and outliers are the unusual features.
my_data %>%
filter(!is.na(my_variable)) %>%
ggplot(aes(x = my_variable)) +
geom_boxplot(fill = "darkseagreen3") +
labs(
title = paste("Boxplot of My Variable in", my_brigade),
x = "My Primary Variable",
y = NULL
) +
theme_minimal()
Write 1–2 sentences: Does the boxplot show possible outliers? How can you tell?
Yes, there are outliers and they appear as individual dots beyond the right whisker of the box plot. They indicate values more than 1.5 x IQR (over 3rd Quartile)
my_data %>%
filter(!is.na(my_variable), !is.na(my_group)) %>%
group_by(my_group) %>%
summarize(
observations = n(),
mean = mean(my_variable),
median = median(my_variable),
standard_deviation = sd(my_variable),
.groups = "drop"
)
## # A tibble: 24 × 5
## my_group observations mean median standard_deviation
## <chr> <int> <dbl> <dbl> <dbl>
## 1 A CO 1-26 AV 80 4.70 3.29 3.97
## 2 A CO 2-16 AV 119 5.01 3.01 4.49
## 3 A CO 3-41 AV 176 4.82 3.55 4.11
## 4 A CO 4-77 GSAB 215 4.86 3.44 4.34
## 5 B CO 1-26 AV 126 4.58 2.92 4.08
## 6 B CO 2-16 AV 124 5.53 4.70 4.52
## 7 B CO 3-41 AV 84 4.83 3.17 4.34
## 8 B CO 4-77 GSAB 184 4.98 3.28 4.14
## 9 C CO 1-26 AV 149 5.26 3.51 4.55
## 10 C CO 2-16 AV 104 4.41 3.13 3.77
## # ℹ 14 more rows
my_data %>%
filter(!is.na(my_variable), !is.na(my_group)) %>%
ggplot(aes(x = my_group, y = my_variable)) +
geom_boxplot(fill = "tan2") +
labs(
title = paste("My Variable by Group in", my_brigade),
x = "My Grouping Variable",
y = "My Primary Variable"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 35, hjust = 1))
Write 2–3 sentences: Which group has the highest center? Which has the greatest spread? Are any groups much smaller than the others?
D CO 1-26 AV has the highest center (median). E CO 3-41 AV has the greatest spread (standard deviation). C CO 4-77 GSAB is the smallest group compared to others.
my_data %>%
filter(!is.na(my_variable), !is.na(my_second_variable)) %>%
ggplot(aes(x = my_second_variable, y = my_variable)) +
geom_point(alpha = 0.5, color = "steelblue4") +
labs(
title = paste("Relationship between My Variables in", my_brigade),
x = "My Second Quantitative Variable",
y = "My Primary Quantitative Variable"
) +
theme_minimal()
Write 2–3 sentences: Is the relationship positive, negative, or not apparent? Does it look strong or weak? Are any observations unusual?
There is no apparent strong positive/negative relationship, the points are widely scattered. Unusual observations include the cluster at the second variable (AFT 2 mile score) at 0 since many soldiers did not test the 2 mile run. There are also some negative primary variable (years of active service) which is unusual.
Write one paragraph that answers all of the following:
I learned that the average years of active service (my primary variable) was around 5 years. By comparing models, I was able to evaluate if there is or is not any correlation between my groups that I wanted to compare. Since I had large amount of data, the points were mainly scattered when comparing the two quantitative variables. However, I can briefly see that the data points with less service years had a greater amount of better AFT 2 mile run. This could mean that the younger population (less active service years) can run faster and get a better score rather that population that has served for many years. I had a lot of missing values for my second variable (AFT 2 mile run score) and it is a concern since it causes me to evaluate less data. For my next investigation, I would question if “soldiers who have good marksmanship skills also have a high AFT score or not?” Through this evaluation, I can check if soldiers need more focus on physical training or more time shooting at the range.
This worksheet is not the full EDA required for your course project. It is an introduction to the basic R tools and exploratory techniques you will need. It is intended to get your foot in the door so that you can begin asking useful questions about your brigade’s data.
After completing this worksheet, you must conduct additional EDA that is specific to your own research question. Use what you discover to develop an original, operationally relevant question for a specific decision maker. Your project EDA should investigate the response and explanatory variables that matter to that question, justify your proxies, examine relevant data-quality concerns, and develop the graphical and numerical evidence needed to motivate the rest of your analysis.
Read AY27-1 MA206 Project Instructions.pdf for the complete project requirements. That document, not this introductory worksheet, is the authoritative source for what your full EDA and final project must contain.
The decision maker for this brigade is Brigade Commander Col Adam R. Bock who leads and makes decisions alongside Command Sergeant Major Njikoka Anderson.
The research question for my EDA: “Do M4 qualification scores differ across time in active service years among soldiers in the same MOS?” Variables from annex B used to research this question are primary specialty code, m4, and time in active service years. There will a primary quantitative variable (time in active service years), a secondary quantitative variable (m4 scores), and a categorical grouping variable (primary specialty code/MOS).
This research will give insight into how much soldiers are prepared for future operations based on lethality. The individual’s marksmanship performance based on their service years can show if more experience is related to better m4 scores. This research will also highlight which MOS has more tendency to have better m4 scores. With answers to this research question, the commander can make decisions for future trainings if needed and it will give them an insight about every MOS preparation.
The construct is to measure m4 marksmanship proficiency, which contributes to soldier lethality. It will be inferred by evaluating the time in active service years for each MOS in the brigade. All three proxies are imperfect due to missing values and conditions under which scores were recorded. For m4 scores, the qualification represents performance under testing conditions rather than combat so even though the scores give an insight into soldier’s marksmanship, it cannot directly guarantee that the performance score will reflect combat effectiveness. There are many other variables and data proxies that can also be used to reflect lethality. For time in active service years, there will be cases where more years reflect high scores, but there will be other cases where more years correlate to low scores. More experience would not necessarily mean better scores and preparedness.
For data cleaning, there will be some missing/negative values for time in active service years and m4 scores. This can lead to This will affect my analysis since I am evaluating which MOS have better m4 scores and if it is correlated to how many years they have served for. Instead of working with all of 2700 records of data for CAB, I would have disregard the data with the missing/negative variables which is 182 data records.
# CHANGE this brigade.
my_brigade <- "CAB"
# CHANGE m4, aft_score_total, and age_bracket to your variables.
# The new names on the left stay the same.
my_data <- army_data %>%
filter(brigade == my_brigade) %>%
transmute(
my_variable = time_in_active_service_years,
my_second_variable = m4,
my_group = primary_specialty_code
)
my_data %>%
summarize(
primary_missing = sum(is.na(my_variable)),
second_missing = sum(is.na(my_second_variable)),
group_missing = sum(is.na(my_group))
)
## # A tibble: 1 × 3
## primary_missing second_missing group_missing
## <int> <int> <int>
## 1 7 175 0
my_data %>%
summarize(
observations = sum(!is.na(my_variable)),
mean = mean(my_variable, na.rm = TRUE),
median = median(my_variable, na.rm = TRUE),
standard_deviation = sd(my_variable, na.rm = TRUE),
iqr = IQR(my_variable, na.rm = TRUE),
minimum = min(my_variable, na.rm = TRUE),
maximum = max(my_variable, na.rm = TRUE)
)
## # A tibble: 1 × 7
## observations mean median standard_deviation iqr minimum maximum
## <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 2693 4.96 3.43 4.28 5.08 -2.83 20.7
my_data %>%
summarize(
observations = sum(!is.na(my_second_variable)),
mean = mean(my_second_variable, na.rm = TRUE),
median = median(my_second_variable, na.rm = TRUE),
standard_deviation = sd(my_second_variable, na.rm = TRUE),
iqr = IQR(my_second_variable, na.rm = TRUE),
minimum = min(my_second_variable, na.rm = TRUE),
maximum = max(my_second_variable, na.rm = TRUE)
)
## # A tibble: 1 × 7
## observations mean median standard_deviation iqr minimum maximum
## <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 2525 29.9 29 5.39 10 23 40
PUT YOUR NAME HERE in the header with your
name.LastName_EDA.Rmd.cadet-choices chunk.LastName_EDA.html file in Canvas
to instructor folder MAJ Ozga → F1 - Project
Folder.If knitting fails, read the first error message. Check the spelling of your brigade and variable names, and confirm that the CSV is in the same folder as the R Markdown file.