1.1 Let’s look again into gapminder
dataset and create a new cloumn, life_level
, that contains five categories (“very high”, “high”,“moderate”, “low” and “very low”) based on life expectancy in 1997. Assign categories accoring to the table below:
Criteria | life_level |
---|---|
less than 23 | very low |
between 23 and 48 | low |
between 48 and 59 | moderate |
between 59 and 70 | high |
more than 70 | very high |
Function case_when()
is a tidier way to vectorise multiple if_else()
statements. you can read more about this function here.
gapminder %>%
filter(year == 1997) %>%
mutate(life_level = case_when(lifeExp < 23 ~ 'very low',
lifeExp < 48 ~ 'low',
lifeExp < 59 ~ 'moderate',
lifeExp < 70 ~ 'high',
TRUE ~ 'very high')) %>%
ggplot() + geom_boxplot(aes(x = life_level, y = gdpPercap)) +
labs(y = "GDP per capita, $", x= "Life expectancy level, years") +
theme_bw()
## Error in gapminder %>% filter(year == 1997) %>% mutate(life_level = case_when(lifeExp < : could not find function "%>%"
Do you notice anything odd/wrong about the graph?
We can make a few observations:
It seems that none of the countries had a “very low” life-expectancy in 1997.
However, since it was an option in our analysis it should be included in our plot. Right?
Notice also how levels on x-axis are placed in the “wrong” order.
1.2 You can correct these issues by explicitly setting the levels parameter in the call to factor()
. Use, drop = FALSE
to tell the plot not to drop unused levels
gapminder %>%
filter(year == 1997) %>%
mutate(life_level = factor(case_when(lifeExp < 23 ~ 'very low',
lifeExp < 48 ~ 'low',
lifeExp < 59 ~ 'moderate',
lifeExp < 70 ~ 'high',
TRUE ~ 'very high') ,
levels = c("very low", "low", "moderate", "high", "very high"))) %>%
ggplot() + geom_boxplot(aes(x = life_level, y = gdpPercap)) +
labs(y = "GDP per capita, $", x= "Life expectancy level, years") +
theme_bw() +
scale_x_discrete(drop=FALSE)
## Error in gapminder %>% filter(year == 1997) %>% mutate(life_level = factor(case_when(lifeExp < : could not find function "%>%"
#factor(), levels need to be specified
In Activity 1, we created our own factors, so now let’s explore what categorical variables that we have in the gapminder
dataset.
gapminder$continent
(activity 2.1)Use functions such as str()
, levels()
, nlevels()
and class()
to answer the following questions:
continent
(a factor or charecter)?class(gapminder$continent)
## Error in eval(expr, envir, enclos): object 'gapminder' not found
nlevels(gapminder$continent)
## Error in levels(x): object 'gapminder' not found
levels(gapminder$continent)
## Error in levels(gapminder$continent): object 'gapminder' not found
str(gapminder$continent)
## Error in str(gapminder$continent): object 'gapminder' not found
gapminder$country
(activity 2.2)Let’s explore what else we can do with factors:
Answer the following questions:
country
?gapminder
dataset by 5 countries of your choice. How many levels are in your filtered dataset?nlevels(gapminder$country)
## Error in levels(x): object 'gapminder' not found
gap = gapminder %>%
filter(country %in% c("China", "Japan", "Albania", "Angola", "Australia"))
## Error in gapminder %>% filter(country %in% c("China", "Japan", "Albania", : could not find function "%>%"
nlevels(gap$country)
## Error in levels(x): object 'gap' not found
gap_dropped <- gap %>%
droplevels()
## Error in gap %>% droplevels(): could not find function "%>%"
gap_dropped$country %>%
nlevels()
## Error in gap_dropped$country %>% nlevels(): could not find function "%>%"
What if we want to get rid of some levels that are “unused” - how do we do that?
The function droplevels()
operates on all the factors in a data frame or on a single factor. The function forcats::fct_drop()
operates on a factor.
h_gap_dropped <- gap %>%
droplevels()
## Error in gap %>% droplevels(): could not find function "%>%"
Let’s say we wanted to re-order the levels of a factor using a new metric - say, count().
We should first produce a frequency table as a tibble using dplyr::count()
:
gapminder %>%
count(continent)
## Error in gapminder %>% count(continent): could not find function "%>%"
The table is nice, but it would be better to visualize the data. Factors are most useful/helpful when plotting data. So let’s first plot this:
gapminder %>%
ggplot() +
geom_bar(aes(continent)) +
coord_flip() +
theme_bw() +
ylab("Number of entries") + xlab("Continent")
## Error in gapminder %>% ggplot(): could not find function "%>%"
Think about how levels are normally ordered. It turns out that by default, R always sorts levels in alphabetical order. However, it is preferable to order the levels according to some principle:
fct_infreq()
might be useful.fct_rev()
will sort them in the opposite order.For instance , `
gapminder %>%
ggplot() +
geom_bar(aes(fct_infreq(continent))) +
coord_flip()+
theme_bw() +
ylab("Number of entries") + xlab("Continent")
## Error in gapminder %>% ggplot(): could not find function "%>%"
Section 9.6 of Jenny Bryan’s notes has some helpful examples.
gapminder
countries by life expectancy, we can visualize the results using fct_reorder()
.## default summarizing function is median()
gapminder %>%
ggplot() +
geom_bar(aes(fct_reorder(continent, lifeExp, max))) +
coord_flip()+
theme_bw() +
xlab("Continent") + ylab("Number of entries")
## Error in gapminder %>% ggplot(): could not find function "%>%"
Use fct_reorder2()
when you have a line chart of a quantitative x against another quantitative y and your factor provides the color.
## order by life expectancy
ggplot(h_gap, aes(x = year, y = lifeExp,
color = FILL_IN_THIS)) +
geom_line() +
labs(color = "country")
## Error in ggplot(h_gap, aes(x = year, y = lifeExp, color = FILL_IN_THIS)): could not find function "ggplot"
This might be useful if you are preparing a report for say, the state of affairs in Africa.
gapminder %>%
ggplot() +
geom_bar(aes(fct_relevel(continent, "Africa", "Americas","Oceania"))) +
coord_flip()+
theme_bw() +
xlab("Continent") + ylab("Number of entries")
## Error in gapminder %>% ggplot(): could not find function "%>%"
More details on reordering factor levels by hand can be found [here] https://forcats.tidyverse.org/reference/fct_relevel.html
Sometimes you want to specify what the levels of a factor should be. For instance, if you had levels called “blk” and “brwn”, you would rather they be called “Black” and “Brown” - this is called recoding. Lets recode Oceania
and the Americas
in the graph above as abbreviations OCN
and AME
respectively using the function fct_recode()
.
gapminder %>%
ggplot() +
geom_bar(aes(fct_recode(continent, "OCN"="Oceania", "AME"="Americas"))) +
coord_flip()+
theme_bw() +
xlab("Continent") + ylab("Number of entries")
## Error in gapminder %>% ggplot(): could not find function "%>%"
Let’s create two data frames,df1
and df2
each with data from two countries, dropping unused factor levels.
The country factors in df1 and df2 have different levels. Can we just combine them?
The country factors in df1
and df2
have different levels. Can you just combine them using c()
?
Explore how different forms of row binding work behave here, in terms of the country variable in the result.