定义超过2个arg的运算符

时间:2016-02-02 20:52:10

标签: r base

我想知道是否有任何方法可以向操作员提供超过2个参数,或者除了使用函数格式之外我别无选择!例如,我可以定义需要超过2个Arg的合并运算符。

这只是一个例子,我对合并功能不感兴趣:

1.我让一个运算符将两个数据框与它们的公共列名A%>>%B合并:

`%>>%`<- function(a,b){
      by.tmp = intersect(names(a),names(b))
      base::merge(a,b,by = by.tmp)
}

2.现在我正在寻找一种方法来定义哪个列应该从data.frame A匹配到data.frame B,例如:

A %column_name_a>>column_name_b% B
# or feeding 2 arg from each side to operator like follow 
# which inside parenthesis return another operator
A (column_name_a %>>% column_name_b) B
# or more advanced
A:column_name_list_a%>>%column_name_list_b:B

我知道如何用函数来做,我只想知道有没有办法定义更复杂的运算符来抽象我的代码。

更新 我设法纠正了一个具有未知数量的参数的运算符(它有点层叠,但它有效)。这是方法:

`%>%` <- function(a,b){

  ifvalid <- function(a, frame = parent.frame()){
    res = try(eval(a,frame),silent = T)
    flag = inherits(res, "try-error") | (length(res)==0)
    ifelse ((!flag) | (length(a)==1) , return(res),  return(
      lapply(a, ifvalid,frame=frame)
      )
    )
  }


  left_arg = substitute(a)
  right_arg= substitute(b)

  res = list(
    left = ifvalid(left_arg),
    right = ifvalid(right_arg)
  )

  return(res)
}

示例运行是:

"X":1:NULL %>% date():`*`
# $left
# $left[[1]]
# .Primitive(":")
# 
# $left[[2]]
# $left[[2]][[1]]
# .Primitive(":")
# 
# $left[[2]][[2]]
# [1] "X"
# 
# $left[[2]][[3]]
# [1] 1
# 
# 
# $left[[3]]
# list()
# 
# 
# $right
# $right[[1]]
# .Primitive(":")
# 
# $right[[2]]
# [1] "Wed Feb 03 16:04:17 2016"
# 
# $right[[3]]
# function (e1, e2)  .Primitive("*")

1 个答案:

答案 0 :(得分:2)

在评论中说明上述方法:

 `%>>%`<- function(a,b){
             base::merge(a,b[[1]],by = b[[2]])
 }

 authors %>>% list(books, "name")
 #-------
      name nationality deceased                         title other.author
1   McNeil   Australia       no     Interactive Data Analysis         <NA>
2   Ripley          UK       no            Spatial Statistics         <NA>
3   Ripley          UK       no         Stochastic Simulation         <NA>
4  Tierney          US       no                     LISP-STAT         <NA>
5    Tukey          US      yes     Exploratory Data Analysis         <NA>
6 Venables   Australia       no Modern Applied Statistics ...       Ripley

使用日期是?merge帮助页面上代码的略微简化版本:

authors <- data.frame(
    name = I(c("Tukey", "Venables", "Tierney", "Ripley", "McNeil")),
    nationality = c("US", "Australia", "US", "UK", "Australia"),
    deceased = c("yes", rep("no", 4)))
books <- data.frame(
    name = I(c("Tukey", "Venables", "Tierney",
             "Ripley", "Ripley", "McNeil", "R Core")),
    title = c("Exploratory Data Analysis",
              "Modern Applied Statistics ...",
              "LISP-STAT",
              "Spatial Statistics", "Stochastic Simulation",
              "Interactive Data Analysis",
              "An Introduction to R"),
    other.author = c(NA, "Ripley", NA, NA, NA, NA,
                     "Venables & Smith"))