R-Purrr的使用,加速数据处理

2022-10-25 14:54:01 浏览数 (1)

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的基本NumberVectordataframelist又个了解。

代码语言:javascript复制
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中。

代码语言:javascript复制
# 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函数可以有不同的输出格式:

代码语言:javascript复制
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将自动绑定每次迭代的行。

代码语言:javascript复制
map_df(c(1, 4, 7), function(.x) {
  return(data.frame(old_number = .x, 
                    new_number = addTen(.x)))
})

请注意,在这种情况下,我定义了一个“匿名”函数作为每次迭代的输出。 匿名函数是一个临时函数(您定义为映射的function参数)。 在这里,我使用了参数名称.x,但我可以使用任何参数。

Modify()

要注意的是另一个函数是Modify(),它与map函数一样,但是始终返回与输入对象具有相同类型的对象

代码语言:javascript复制
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

0 人点赞