library(dslabs)
data(murders)
data("na_example")

Exercise 1 - Inspect the Data Structure

str(murders)
## 'data.frame':    51 obs. of  5 variables:
##  $ state     : chr  "Alabama" "Alaska" "Arizona" "Arkansas" ...
##  $ abb       : chr  "AL" "AK" "AZ" "AR" ...
##  $ region    : Factor w/ 4 levels "Northeast","South",..: 2 4 4 2 4 4 1 2 2 2 ...
##  $ population: num  4779736 710231 6392017 2915918 37253956 ...
##  $ total     : num  135 19 232 93 1257 ...

There are 51 observations and 5 variables. State and abb are character variables, region is a factor, and population and total are numerical. The data frame gives each statesname, abbreviation, region, population, and total number of gun murders.

Exercise 2 - Summarize Categorical Variable

table(murders$region)
## 
##     Northeast         South North Central          West 
##             9            17            12            13

The south has the largest number of observations while the Northeast has the smallest.

Exercise 3 - Diagnose and Handle Missing Values

ind <- is.na(na_example)
sum(ind)
## [1] 145

There are 145 missing values.

mean(na_example[!ind])
## [1] 2.301754
mean(na_example, na.rm = TRUE)
## [1] 2.301754
mean(na_example)
## [1] NA

Since the vector contains missing values, the mean() function does not ignore them unless specifically told to remove them.

Exercise 4 - Construct an Analysis Variable

murder_rate <- murders$total / murders$population * 100000
mean_murder_rate <- mean(murder_rate)
round(mean_murder_rate, 2)
## [1] 2.78

The mean of the state-level murder rate is 2.78 murders per 100,000 residents. A rate is more useful than raw numbers of murders because the states have a variety of population sizes. Using a rate make comparisons between the large versus smaller states meaningful.

Exercise 5 - Filter With Multiple Conditions

low <- murder_rate < 1 
northeast <- murders$region == "Northeast"

ind <- low & northeast
murders$state[ind]
## [1] "Maine"         "New Hampshire" "Vermont"
sum(ind)
## [1] 3

There are 3 (Maine, New Hampshire, and Vermont) states in the Northeast with murders rates below 1 per 100,000.

Exercise 6 - Compare Raw and Log Scales

population_in_millions <- murders$population / 10^6
total_gun_murders <- murders$total

#Original Scale

plot(population_in_millions, total_gun_murders,
     main = "Total Murders vs. State Population",
     xlab = "Population (millions)",
     ylab = "Total Murders")

#Log10Scale

log_population <- log10(population_in_millions)
log_murders <- log10(total_gun_murders)

plot(log_population, log_murders,
     main = "Total Murders vs. Population on Log 10 Scale",
     xlab = "Log10 Population (millions)",
     ylab = "Log 10 Total Murders")

In the original scale, many of the smaller states are custers togethernear the lower left portion of the gragh. On the other hand, states with very large populations are farther away from the rest. There is a positive association between population and total murders. The log function spreads out the smaller observations and reduces the influence of extremely large values. This makes it easier to see the gragh and in turn, interpret it.

Exercise 7 - Visualize a Distribution

population_in_millions <- murders$population / 10^6

hist(population_in_millions,
     main = "Distribution of State Populations",
     xlab = "Population (millions)")

The distribtuion of state populations is right-skewed. Most states are on the lower end of the population range. A few states have mauch larger populations than the rest, especially in California and Texas.

Exercise 8 - Compare Groups

boxplot(population_in_millions ~ murders$region,
        main = "State Population by Region",
        xlab = "Region",
        ylab = "Population (millions)")

The regional population distribution have different centers and spreads. The North Central and South regions have higher populations while the West has lower. The South contains large population values, specifically in Texas and Florida, so the distribution is a wider upper range.

Exercise 9 - Create a Ranked Data Frame

ranks <- rank(murders$population)

my_df <- data.frame(
  state = murders$state,
  region = murders$region,
  population_in_millions = murders$population / 10^6,
  population_rank = ranks
)

head(my_df)
##        state region population_in_millions population_rank
## 1    Alabama  South               4.779736              29
## 2     Alaska   West               0.710231               5
## 3    Arizona   West               6.392017              36
## 4   Arkansas  South               2.915918              20
## 5 California   West              37.253956              51
## 6   Colorado   West               5.029196              30

The smallest population received a ranking of 1, while the largest population received a ranking of 51.

Exercise 10 - Order Data for Graghical Reasoning

ind <- order(my_df$population_in_millions)

my_df_orders <- my_df[ind, ]

head(my_df_orders)
##                   state        region population_in_millions population_rank
## 51              Wyoming          West               0.563626               1
## 9  District of Columbia         South               0.601723               2
## 46              Vermont     Northeast               0.625741               3
## 35         North Dakota North Central               0.672591               4
## 2                Alaska          West               0.710231               5
## 42         South Dakota North Central               0.814180               6
tail(my_df_orders)
##           state        region population_in_millions population_rank
## 39 Pennsylvania     Northeast               12.70238              46
## 14     Illinois North Central               12.83063              47
## 33     New York     Northeast               19.37810              48
## 10      Florida         South               19.68765              49
## 44        Texas         South               25.14556              50
## 5    California          West               37.25396              51
all(diff(my_df_orders$population_in_millions) >= 0)
## [1] TRUE

The program shows that the observations are orders from smallest to largest in population. Ordering data can make reading and interpreting it easier because the viewer can quickly recongnize increases, decreases, extremes, and other patterns. If this were not ordered, these same values would appear scattered across a gragh and making conclusions would become harder.