R语言学习(因子变量和函数)
前言
R语言的一些基础知识基本结束,明天开始可视化进一步的内容。对于这些基础知识的学习,感触是,不经过实际数据进行反复练习,很多语法还是记不清楚,基本只能有个大概的了解,下次使用的时候还是会翻看。
因子型变量
创建因子
library(tidyverse)
library(palmerpenguins)
income <- c("low", "high", "medium", "medium", "low", "high", "high")
factor(income)
#[1] low high medium medium low high high
#Levels: high low medium
调整因子顺序
x <- factor(income)
x %>% fct_relevel(levels = c("high", "medium", "low"))
# [1] low high medium medium low high high
# Levels: high medium low
将”medium“移动到最前面
x %>% fct_relevel(levels = c("medium"))
# [1] low high medium medium low high high
# Levels: medium high low
将medium移动到最后
x %>% fct_relevel("medium", after = Inf)
# [1] low high medium medium low high high
# Levels: high low medium
按照字符串第一次出现的顺序
x %>% fct_inorder()
# [1] low high medium medium low high high
# Levels: low high medium
按照其他变量的中位数的升序排序
fct_reorder()
可以让x的顺序按照x中每个分类变量对应y值的中位数升序排序,具体为
d %>%
ggplot(aes(x = fct_reorder(x, y, .fun = median), y = y)) +
geom_point()
x %>% fct_reorder(c(1:7), .fun = median)
# [1] low high medium medium low high high
# Levels: low medium high
应用
主要是在可视化中分类变量顺序调整的应用
ggplot(penguins, aes(y = fct_relevel(species, "Chinstrap"))) +
geom_bar()
ggplot(penguins, aes(y = fct_relevel(species, "Adelie", after = Inf))) +
geom_bar()
penguins %>%
mutate(species = fct_infreq(species)) %>%
ggplot(aes(y = species)) +
geom_bar()
penguins %>%
mutate(species = fct_rev(fct_infreq(species))) %>%
ggplot(aes(y = species)) +
geom_bar()
library(gapminder)
gapminder %>%
filter(
year == 2007,
continent == "Americas"
)
gapminder %>%
filter( year == 2007, continent == "Americas") %>%
mutate( country = fct_reorder(country, lifeExp)) %>%
ggplot(aes(lifeExp, country)) +
geom_point()
gapminder %>%
filter(country %in% c("Norway", "Portugal", "Spain", "Austria")) %>%
ggplot(aes(year, lifeExp)) + geom_line() +
facet_wrap(vars(country), nrow = 1)
gapminder %>%
filter(country %in% c("Norway", "Portugal", "Spain", "Austria")) %>%
mutate(country = fct_reorder(country, lifeExp)) %>% # default: order by median
ggplot(aes(year, lifeExp)) + geom_line() +
facet_wrap(vars(country), nrow = 1)
要求给四个分面排序,按每个国家寿命差(最大值减去最小值)
gapminder %>%
filter(country %in% c("Norway", "Portugal", "Spain", "Austria")) %>%
# order by custom function: here, difference between max and min
mutate(country = fct_reorder(country, lifeExp, function(x) { max(x) - min(x) })) %>%
ggplot(aes(year, lifeExp)) + geom_line() +
facet_wrap(vars(country), nrow = 1)
函数式编程
map函数
map()函数的第一个参数是list或vector,第二个参数是函数
就是将函数应用到list/vector的每一个参数
library(tidyverse)
exams <- list(
student1 = round(runif(10, 50, 100)),
student2 = round(runif(10, 50, 100)),
student3 = round(runif(10, 50, 100)),
student4 = round(runif(10, 50, 100)),
student5 = round(runif(10, 50, 100))
)
map(exams,mean)
$student1
[1] 79
$student2
[1] 74.2
$student3
[1] 64.2
$student4
[1] 75.3
$student5
[1] 76.8
执行过程
map家族
如果希望返回的是数值型向量,可以写map_dbl()
eaxms %>% map_dbl(mean)#输出的结果为向量
如果希望返回的结果是数据框
exams %>% map_df(mean)#返回的结果是数据框
map的其它参数
map(exams,sort)#表示将每位同学的成绩排序,默认的是升序
map(exams,sort,decreasing=TRUE)#将升序改为降序
匿名函数
在定义函数时不对函数进行命名,函数没有名字。
比如
function(x) x-mean(x)
exams%>%
map(function(x)) x-mean(x)
#还可以用~代替function(),但参数必须是规定的写法
exams%>%map(~.x-mean(.x))
#有时候,只用.也是可以的
exams%>%map(~.-mean(.))
#~告诉map()后面跟随的是一个匿名函数,对应函数的参数可以认为是一个占位符
在dplyr函数中运用map
tibble的本质是向量构成的列表,因此tibble也适用于map
tb <-
tibble(
col_1 = c(1, 2, 3),
col_2 = c(100, 200, 300),
col_3 = c(0.1, 0.2, 0.3)
)
map()可以作用到tb的每一列,求每一列的中位数
map_dbl(tb,median)
找出每一列缺失值的数量
palmerpenguins::penguins %>%
map_int(~ sum(is.na(.)))
map2()
map2()和map()函数类似,不同在于map2()接受两个的向量,这两个向量必须是等长的。在map()
函数使用匿名函数,可以用 .
代表输入向量的每个元素。在map2()
函数, .
不够用,所有需要需要用 .x
代表第一个向量的元素,.y
代表第二个向量的元素。
x <- c(1, 2, 3)
y <- c(4, 5, 6)
map2(x, y, ~ .x + .y)
df <-
tibble(
a = c(1, 2, 3),
b = c(4, 5, 6)
)
df %>%
mutate(min = map2_dbl(a, b, ~min(.x, .y)))
pmap()
-
map()
和map2()
函数,指定传递给函数f的向量,向量各自放在各自的位置上 -
pmap()
需要将传递给函数的向量名,先装入一个list()中, 再传递给函数f
pmap_dbl(list(x, y), min)
因为tibble本质就是list,因此pmap可以直接将其应用导函数。
tibble(
a = c(50, 60, 70),
b = c(10, 90, 40),
c = c(1, 105, 200)
) %>%
pmap_dbl(min)
pmap()
可以接受多个向量,因此在pmap()
种使用匿名函数,就需要一种新的方法来标识每个向量。由于向量是多个,因此不再用.x
, .y
,而是用..1
, ..2
, ..3
分别代表第一个向量、第二个向量和第三个向量。