R-Purrr的使用,加速数据处理
Tidyverse
中包含一个purrr
程序包,之前在看数据处理分析时候,一直看到别人的code中,涵盖purrr,map
函数,但是一直不知道这个是干什么的,现在发现purrr真的是极大的加速了数据处理流程,减少了code的编写。
Purrr 主要是替换for循环的使用。
Purrr
引入了map
函数以及一些用于操纵list的新函数。cheatsheet可以速查一些关于Tidyverse使用方法。在了解purrr之前,需要掌握一些关于Tidyverse的基础。
关于Purrr的教程可以参考詹妮·布赖恩(Jenny Bryan)的教程。 珍妮的教程很棒,但比我的要教程长得多。需要耐心学些。
这篇文章是快速教你使用purrr。
因为Purrr的操作对象基本上都是关于list
,所以对R的基本Number
,Vector
,dataframe
及list
又个了解。
my_first_list <- list(my_number = 5,
my_vector = c("a", "b", "c"),
my_dataframe = data.frame(a = 1:3, b = c("q", "b", "z"), c = c("bananas", "are", "so very great")))
my_first_list
Map functions: beyond apply
map
函数是对list
或者vector
进行统一类似的函数操作,譬如对不同性别求平均年龄等,与apply
函数相似。
apply()
函数是一组超级有用的base-R函数,可用于vector或list的条目迭代执行操作,而无需编写for循环。尽管基本R Apply函数从根本上没有什么错,但不同的Apply函数的语法在某种程度上是不一致的,并且它们返回的对象的预期类型通常是模棱两可的,有的返回vector有的返回list。当然了,map
函数也有根据需要返回不同数据类型:
- map(.x, .f) is the main mapping function and returns a list
- map_df(.x, .f) returns a data frame
- map_dbl(.x, .f) returns a numeric (double) vector
- map_chr(.x, .f) returns a character vector
- map_lgl(.x, .f) returns a logical vector
与tidyverse的方式一致,每个映射函数的第一个参数始终是要映射的数据对象,第二个参数始终是要迭代地应用于输入对象的每个元素的函数。
map 循环例子1
譬如我们对c(1, 4, 7)
进行每个数➕10
,我们有.x
vetcor数据,然后编写.f
funtion数据,合并到map中。
# add function
addTen <- function(.x) {
return(.x 10)
}
# map
library(tidyverse)
map(.x = c(1, 4, 7),
.f = addTen)
## [[1]]
## [1] 11
##
## [[2]]
## [1] 14
##
## [[3]]
## [1] 17
map(c(1, 4, 7), addTen)
或者直接 map(c(1, 4, 7), addTen)
,当然了上面介绍了map
函数可以有不同的输出格式:
map(c(1, 4, 7), addTen) # list
map(list(1, 4, 7), addTen) # list
map(data.frame(a = 1, b = 4, c = 7), addTen) # dataframe
map_dbl(c(1, 4, 7), addTen) # vector
map_chr(c(1, 4, 7), addTen) # string
如果要返回 dataframe,则可以使用map_df()
函数。
但是,您需要确保在每次迭代中都返回一个具有一致列名的数据框。
map_df将自动绑定每次迭代的行。
map_df(c(1, 4, 7), function(.x) {
return(data.frame(old_number = .x,
new_number = addTen(.x)))
})
请注意,在这种情况下,我定义了一个“匿名”函数作为每次迭代的输出。 匿名函数是一个临时函数(您定义为映射的function参数)。 在这里,我使用了参数名称.x,但我可以使用任何参数。
Modify()
要注意的是另一个函数是Modify()
,它与map
函数一样,但是始终返回与输入对象具有相同类型的对象
library(tidyverse)
modify(c(1, 4, 7), addTen)
modify(list(1, 4, 7), addTen)
modify(data.frame(1, 4, 7), addTen)
modify_if(.x = list(1, 4, 7),
.p = function(x) x > 5,
.f = addTen)
参考
purrr