R:将参数传递给 outer()

R: pass args to outer()

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)

缺少什么?

您可以使用 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

我建议使用 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 起作用。

向量化参数意味着您的函数可以将向量作为参数(!)。正如@Roland 在评论中所述,您的函数需要专门设置才能与 outer 一起使用。所以前两个参数应该被向量化。这意味着您可以为 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