R语言中的函数5:purrr:map()_zoujiahui_2018的博客-程序员宝宝_r语言map函数

技术标签: R  r语言  回归  开发语言  

前言

**map()**类函数在很大程度上替代了循环的作用,并且计算中利用的多线程并行计算,多使用不但可以提高计算效率还可以让代码更加整洁。

map(.x,.f,…),map2(.x,.y,.f,…),pmap(.I,.f,…)

  • x,y这里可以是atomic vector(向量或矩阵)或是list(列表,数据框),长度要相等。
  • map(x, f),map2(x,y,f),pmap(I,f)返回的是一个和x有同样长度的list.
  • map2()中变量长度必须相同,这点没有python灵活。
  • 在pmap()函数中,I是一个list, f是个多元函数每次从list的每个原子中选一个对象进行计算。
  • f 是一个函数,或者是一个公式例如: ~ x + 2
  • …表示.f所需的参数。

数据准备

library(purrr)
fun=function(x){
    x+1}
funxy=function(x,y){
    x-y}
x=c(1,5,8,9)
X=list(1,2,6,5)
y=c(8,4,6,2)
z=c(1,4,8,6)

map()测试

x是vector的情况:

res=map(x,fun);res
# [[1]]
# [1] 2
# 
# [[2]]
# [1] 6
# 
# [[3]]
# [1] 9
# 
# [[4]]
# [1] 10

x包含list的情况:

res=map(X,fun);res
# [[1]]
# [1] 2
# 
# [[2]]
# [1] 3
# 
# [[3]]
# [1] 7
# 
# [[4]]
# [1] 6

map2()测试

res=map2(x,y,funxy);res
# [[1]]
# [1] -7
# 
# [[2]]
# [1] 1
# 
# [[3]]
# [1] 2
# 
# [[4]]
# [1] 7

如果被映射变量长度不同就会报错:

y2=c(8,4)
res=map2(x,y2,funxy);res
# 错误: Mapped vectors must have consistent lengths:
#   * `.x` has length 4
#   * `.y` has length 2

list与vector混合的情况:

res=map2(X,y,funxy);res
# [[1]]
# [1] -7
# 
# [[2]]
# [1] -2
# 
# [[3]]
# [1] 0
# 
# [[4]]
# [1] 3

pmap()测试

funxyz=function(x,y,z){
    x+y+z}
I=list(X,y,z)
res=pmap(I,funxyz);res
# [[1]]
# [1] 10
# 
# [[2]]
# [1] 10
# 
# [[3]]
# [1] 20
# 
# [[4]]
# [1] 13

map_lgl(),map2_lgl(),pma_lgl()

返回逻辑向量

library(purrr)
fun=function(x){
    x>1}
funxy=function(x,y){
    x>y}
funxyz=function(x,y,z){
    x>y-z}
y=c(8,4,6,2)
x=c(1,5,8,9)
z=c(9,5,4,6)
mydata=data.frame(x,y,z)


res=map_lgl(x,fun);res
#[1] FALSE  TRUE  TRUE  TRUE

res=map2_lgl(x,y,funxy);res
#[1] FALSE  TRUE  TRUE  TRUE

res=pmap_lgl(mydata,funxyz);res
# [1] TRUE TRUE TRUE TRUE

map_chr(), map2_chr(), pmap_chr(),

返回字符串向量

library(purrr)
fun=function(x){
    as.character(x)}
funxy=function(x,y){
    paste0(as.character(x),as.character(y))}
funxyz=function(x,y,z){
    paste0(as.character(x),as.character(y),as.character(z))}
y=c(8,4,6,2)
x=c(1,5,8,9)
z=c(9,5,4,6)
mydata=data.frame(x,y,z)


res=map_chr(x,fun);res
# "1" "5" "8" "9"

res=map2_chr(x,y,funxy);res
# "18" "54" "86" "92"

res=pmap_chr(mydata,funxyz);res
# "189" "545" "864" "926"

map_dbl(),map2_dbl(),pmap_dbl()

返回的是一个双精度向量

library(purrr)
fun=function(x){
    x+0.11}
funxy=function(x,y){
    x-y+0.69}
funxyz=function(x,y,z){
    x-y-z-0.554}
y=c(8,4,6,2)
x=c(1,5,8,9)
z=c(9,5,4,6)
mydata=data.frame(x,y,z)


res=map_dbl(x,fun);res
# [1] 1.11 5.11 8.11 9.11

res=map2_dbl(x,y,funxy);res
# [1] -6.31  1.69  2.69  7.69

res=pmap_dbl(mydata,funxyz);res
# [1] -16.554  -4.554  -2.554   0.446

map_dfr(), map2_dfr(), pmap_dfr()

返回一个dataframe, 是由每个f(x)输出rbind后的结果,因此也需要f的返回是一个dataframe。

 library(purrr)
fun=function(x){
    data.frame(var1=x+0.11,var2=x)}
funxy=function(x,y){
    data.frame(var1=x-y+0.69,var2=x)}
funxyz=function(x,y,z){
    data.frame(var1=x-y-z-0.554,var2=x+y+z)}
y=c(8,4,6,2)
x=c(1,5,8,9)
z=c(9,5,4,6)
mydata=data.frame(x,y,z)


res=map_dfr(x,fun);res
# var1 var2
# 1 1.11    1
# 2 5.11    5
# 3 8.11    8
# 4 9.11    9

res=map2_dfr(x,y,funxy);res
# var1 var2
# 1 -6.31    1
# 2  1.69    5
# 3  2.69    8
# 4  7.69    9

res=pmap_dfr(mydata,funxyz);res
# var1 var2
# 1 -16.554   18
# 2  -4.554   14
# 3  -2.554   18
# 4   0.446   17

map_dfc(), map2_dfc(), pmap_dfc()

返回一个dataframe, 是由每个f(x)输出cbind后的结果,因此也需要f的返回是一个可以被cbind的输出。

library(purrr)
fun=function(x){
    data.frame(var1=x+0.11,var2=x)}
funxy=function(x,y){
    c(x-y+0.69,x)}
funxyz=function(x,y,z){
    data.frame(var1=x-y-z-0.554,var2=x+y+z)}
y=c(8,4,6,2)
x=c(1,5,8,9)
z=c(9,5,4,6)
mydata=data.frame(x,y,z)


res=map_dfc(x,fun);res
# var1 var2 var11 var21 var12 var22 var13 var23
# 1 1.11    1  5.11     5  8.11     8  9.11     9

res=map2_dfc(x,y,funxy);res
# # A tibble: 2 x 4
# V1    V2    V3    V4
# <dbl> <dbl> <dbl> <dbl>
#   1 -6.31  1.69  2.69  7.69
#   2  1     5     8     9   

res=pmap_dfc(mydata,funxyz);res
# var1 var2  var11 var21  var12 var22 var13 var23
# 1 -16.554   18 -4.554    14 -2.554    18 0.446    17

map_if(.x,.p,.f,.else),map_at(.at.x,.p,.f,.else)

这里.p是判断函数,.f是判断为真的执行语句,.else是判断为假的执行语句,.at可以是字符串或者数值索引,表示对.x中这些对象起作用。注意这里的作用单元是list或vector中的每个原子,而非横向地从每个原子中取元素执行。

library(purrr)
fun=function(x){
    sum(x)>8}
x=c(1,5,8,9)
y=c(9,8,5,3)
z=c(-1,-2,5,3)
mydata=data.frame(x=x,y=y,z=z)
res=map_if(.x=x,.p=fun,.f=~'right',.else=~'wrong');res
# [[1]]
# [1] "wrong"
# 
# [[2]]
# [1] "right"
# 
# [[3]]
# [1] "right"
# 
# [[4]]
# [1] "right"

res=map_if(.x=mydata,.p=fun,.f=sum,.else=~'wrong');res
# $x
# [1] 23
# 
# $y
# [1] 20
# 
# $z
# [1] "wrong"



res=map_at(.at=2:3,.x=x,.p=fun,.f=~'right',.else=~'wrong');res
# [[1]]
# [1] 1
# 
# [[2]]
# [1] "right"
# 
# [[3]]
# [1] "right"
# 
# [[4]]
# [1] 9


res=map_at(.at=2:3,.x=mydata,.p=fun,.f=~'right',.else=~'wrong');res
# $x
# [1] 1 5 8 9
# 
# $y
# [1] "right"
# 
# $z
# [1] "right"

说明文档中的一些例子

1:10 %>%
  map(rnorm, n = 10) %>%
  map_dbl(mean)

# Or use an anonymous function
1:10 %>%
  map(function(x) rnorm(10, x))

# Or a formula
1:10 %>%
  map(~ rnorm(10, .x))



# Using set_names() with character vectors is handy to keep track
# of the original inputs:
set_names(c("foo", "bar")) %>% map_chr(paste0, ":suffix")





# Supply multiple values to index deeply into a list
l2 <- list(
  list(num = 1:3,     letters[1:3]),
  list(num = 101:103, letters[4:6]),
  list()
)
l2 %>% map(c(2, 2))






# A more realistic example: split a data frame into pieces, fit a
# model to each piece, summarise and extract R^2
mtcars %>%
  split(.$cyl) %>%
  map(~ lm(mpg ~ wt, data = .x)) %>%
  map(summary) %>%
  map_dbl("r.squared")





# If each element of the output is a data frame, use
# map_dfr to row-bind them together:
mtcars %>%
  split(.$cyl) %>%
  map(~ lm(mpg ~ wt, data = .x)) %>%
  map_dfr(~ as.data.frame(t(as.matrix(coef(.)))))
# (if you also want to preserve the variable names see
# the broom package)
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_18055167/article/details/104437236

智能推荐

时间换算_crescentgear的博客-程序员宝宝

题目内容:UTC是世界协调时,BJT是北京时间,UTC时间相当于BJT减去8。现在,你的程序要读入一个整数,表示BJT的时和分。整数的个位和十位表示分,百位和千位表示小时。如果小时小于10,则没有千位部分;如果小时是0,则没有百位部分;如果分小于10分,需要保留十位上的0。如1124表示11点24分,而905表示9点5分,36表示0点36分,7表示0点7分。有效的输入范围是0到2359,即...

不能插入数据,查看谁锁表,解锁_weixin_33698043的博客-程序员宝宝

为什么80%的码农都做不了架构师?&gt;&gt;&gt; ...

ubuntu 12.04 安装在VMware 8不能共享文件解决办法_bingqingsuimeng的博客-程序员宝宝

Ubuntu社区已经推出了ubuntu 12.04 beat1版,最近安装在vmware里体验了一把。不过在设置文件共享的时候,发现ubuntu 12.04中不能正常挂载出共享目录。网上查了些资料,说要安装补丁,照上面做了,在运行补丁脚本的那一步出现了问题,报错信息大概是提示我vmware-tools没有安装。可是我明明安装过了。为什么会报这个错误呢,通过查看脚本文件,发现里面有个命令我本

单细胞文献分析 Quantitative single-cell rna-seq with unique molecular identifers_weixin_30776545的博客-程序员宝宝

Quantitative single-cell rna-seq with unique molecular identifers 这篇文章论证了 scRNA-seq 使用UMI来计算基因表达量的合理性和优势。 这里主要研究如何分析 scRNA-seq 的数据,如何处理ERCC和UMI。 背景: however, losses in cdna synthesis and bias in cdn...

在卸载或更改程序中不显示已安装程序的方法_weixin_34346099的博客-程序员宝宝

打开注册表,然后搜索在卸载或更改程序中改程序显示的信息(比如要找百度云管家,可以搜索“百度在线网络技术”)。找到后将DisplyName改成DoNotDisplayName或者其它名字,这样在卸载或更改程序列表就找不到该程序了。要恢复显示也简单,只需把名字改回DisplayName即可。   ...

053-418_dieqiao8331的博客-程序员宝宝

Using Oracle Enterprise Manager to set SGA pool values manually, for which of the following pools does Oracle EM offer advice to set the value appropriately? (Choose all that apply.)A. DB_CACHE_S...

随便推点

HDU 5787 K-wolf Number(数位DP)_AC_Arthur的博客-程序员宝宝

题目链接:点击打开链接思路:我们用dp[cur][a][b][c][d][p]表示当前到了第cur位,前四位分别是abcd并且当前是否已经小于给定的数的方案数。  我们分别算出L和R的dp值,  以及L是否符合要求, 做差并把多减的加上即可。  比赛时写的比较恶心, 不是很美观但是很直观。细节参见代码:#include #include #include #include

bios 微星click_微星主板CLICK BIOS II BIOS设置软件_weixin_39615984的博客-程序员宝宝

微星科技独家ClickBIOS II,不但是全球第一个整合UEFI BIOS跟Windows应用程式的系统工具,可以分别在不同的环境下,透过滑鼠甚至是触控面板来调校系统设定,相对于往常产品只能提供UEFI BIOS或者Windows应用程式,ClickBIOS II更贴近了一般使用者的习惯与操作模式,带来了绝佳的便利性与高度的技术整合,并可以透过ClickBIOS II内的实用软体,达到线上升级驱...

软考网工主要考什么?有什么用?_wlq7777的博客-程序员宝宝_软考网络工程师考什么

什么是软考网络工程师:网络工程师属于软考中的一个中级考试,软考设三个级别层次,五个专业,共有27种岗位资格考试网络工程师是通过学习和训练,掌握网络技术的理论知识和操作技能的网络技术人员。网络工程师能够从事计算机信息系统的设计、建设、运行和维护工作。网络工程师是指基于硬、软件两方面的工程师,根据硬件和软件的不同、认证的不同,将网络工程师划分成很多种类。网络工程师分硬件网络工程师和软件网络工程师两大类,硬件网络工程师以负责网络硬件等物理设备的维护和通信;软件网络工程师负责系统软件,应用软件等的维护和应用。.

使用 React Native 中遇到的一些问题_niuiic的博客-程序员宝宝

更多分享内容可访问我的个人博客https://www.niuiic.top/本文记录在使用 React Native 中遇到的一些问题及解决方法。卡在 info Starting JS server…如果你的网络没有问题,即没有被墙,那么一般可以使用以下方法解决。为了测试,首先新建一个项目,npx react-native init AwesomeProject。然后使用 Android Studio 打开项目的 android 目录,并且开启模拟器。然后就不要动 IDE 里的东西,尤其是一些升

Pots POJ - 3414_chenghuang_yi的博客-程序员宝宝

Pots POJ - 3414小明给你两个容器,分别能装下A升水和B升水,并且可以进行以下操作FILL(i) 将第i个容器从水龙头里装满(1 ≤ i ≤ 2);DROP(i) 将第i个容器抽干POUR(i,j) 将第i个容器里的水倒入第j个容器(这次操作结束后产生两种结果,一是第j个容器倒满并且第i个容器依旧有剩余,二是第i个容器里的水全部倒入j中,第i个容器为空)现在要求你写一个程序,来找出能使其中任何一个容器里的水恰好有C升,找出最少操作数并给出操作过程

数组拆分_一个回和的博客-程序员宝宝_数组拆分

目录1.横向拆分 hsplit()2.纵向拆分 vsplit()3.split()1.横向拆分 hsplit()import nmupy as nparr=np.arange(16).reshape(4,4)print('arr:',arr)#横向拆分 平分arr_new=np.hsplit(arr,2)print('arr_new:',arr_new)...