R:将args传递给outer()

时间:2015-07-06 15:44:47

标签: r combinations dplyr

set.seed(8)
data <- 
  data.frame(A=rnorm(10),
             B=rnorm(10))



fun <- function(df,x,y){
  require(dplyr)
  res <- 
    filter(df,A<x,B>y) %>%
    nrow()
  return(res)
}

这适用于x和y的单个值:

fun(x=1,y=0,df=data)

我想使用outer()(或类似的)来组合x和y,但无法弄清楚如何传递df参数。它似乎与此处的问题相同: Using outer() with a multivariable function。 但是通过...传递df不起作用:

outer(x=c(0,2),y=c(0,2),fun,df=data)

缺少什么?

3 个答案:

答案 0 :(得分:5)

我建议使用cut

# borrowing the @Colonel's example:
x = c(0,1,2)
y = c(-1,0,2)

library(magrittr)
data %<>% mutate(
  Ag = cut(A,c(-Inf,x,Inf)), 
  Bg = cut(B,c(-Inf,y,Inf))
)

with(data, table(Ag,Bg))
#           Bg
# Ag         (-Inf,-1] (-1,0] (0,2] (2, Inf]
#   (-Inf,0]         1      4     3        0
#   (0,1]            0      0     2        0
#   (1,2]            0      0     0        0
#   (2, Inf]         0      0     0        0

这可能与OP之后的不等式不匹配,但我怀疑某些变化可以解决问题。请注意,xy必须按cut排序才能生效。

答案 1 :(得分:3)

您可以使用Currymapply

library(functional)

df = expand.grid(c(1,2,0),c(-1,2,0))

mapply(Curry(fun, df=data), df[,1],df[,2])
#[1] 9 9 7 0 0 0 5 5 3

答案 2 :(得分:3)

向量化参数意味着你的函数可以将向量作为参数(!)。正如@Roland在评论中所述,您的功能需要专门设置才能与outer一起使用。所以前两个args应该是矢量化的。这意味着您可以传递xy的参数向量,并且将在两者的每个值上调用该函数。您可以使用Vectorize功能轻松完成此操作。

fun <- Vectorize(function(x, y, df){
  require(dplyr)
  res <- 
    filter(df,A<x,B>y) %>%
    nrow()
  return(res)
}, vectorize.args=c("x", "y"))


outer(c(0,1,2), c(-1,0,2), fun, df=data)

#      [,1] [,2] [,3]
# [1,]    7    3    0
# [2,]    9    5    0
# [3,]    9    5    0