Мне интересно, есть ли способ передать оператору более двух аргументов, или у меня нет другого выбора, кроме как использовать формат функции! Например, я мог бы определить оператор слияния, для которого требуется более 2 аргументов.
Вот просто пример, меня не интересует функциональность слияния:
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("*")