关于R当中的mapply

之前的博客《R数据分析当中的化整为零(Split-Apply-Combine)策略》以及《关于R当中的tapply》有提到一些关于lapply, sapply, vapply和tapply的内容。对于mapply只是粗粗带过。但很多时候,使用mapply可以帮助我们大大提高效率。我们先来看一个非常时用的函数yapply。

yapply <- function(X,FUN, ...) { 
  index <- seq(length.out=length(X)) 
  namesX <- names(X) 
  if(is.null(namesX)) 
    namesX <- rep(NA,length(X))
 
  FUN <- match.fun(FUN) 
  fnames <- names(formals(FUN)) 
  if( ! "INDEX" %in% fnames ){ 
    formals(FUN) <- append( formals(FUN), alist(INDEX=) )   
  } 
  if( ! "NAMES" %in% fnames ){ 
    formals(FUN) <- append( formals(FUN), alist(NAMES=) )   
  } 
  mapply(FUN,X,INDEX=index, NAMES=namesX,MoreArgs=list(...)) 
}

使用这个yapply,它非常类似lapply,所不同的是,它可以在函数中使用NAMES以及INDEX两个变量,这两个变量分别是list的names以及索引号。当有两个索引号相关的数据,或者名称相关的数据需要在一个lapply中进行操作的时候,就变得非常方便。比如

> a <- 1:10
> names(a) <- letters[1:10]
> b <- 2:11
> names(b) <- letters[2:11]
> a
 a  b  c  d  e  f  g  h  i  j 
 1  2  3  4  5  6  7  8  9 10 
> b
 b  c  d  e  f  g  h  i  j  k 
 2  3  4  5  6  7  8  9 10 11 
> aplusb<-function(.a,.b){.a+.b}
> mapply(aplusb,as.list(a),as.list(b))
 a  b  c  d  e  f  g  h  i  j 
 3  5  7  9 11 13 15 17 19 21 
> aplusbByname <- function(.a, NAMES){if(NAMES %in% names(b)) .a+b[[NAMES]] else .a}
> mapply(aplusbByname,as.list(a),names(a))
 a  b  c  d  e  f  g  h  i  j 
 1  4  6  8 10 12 14 16 18 20

mapply的原型是:mapply(FUN, …, MoreArgs = NULL, SIMPLIFY = TRUE,
USE.NAMES = TRUE)
其中…可以是一系列长度相等的list/vector等。它们是做为FUN的参数一一对应的传入FUN当中去使用。由此可以,mapply是处理多个有关联的list以及vector的好帮手。

Leave a Reply

  

  

  

%d 博主赞过: