R:在用户定义的函数上使用external()

时间:2018-10-21 23:06:53

标签: r vectorization user-defined-functions

我想将用户定义的函数与outer函数一起使用。我想将两个向量元素的每种组合都用作函数myfun的参数。

v1= c(30, 60, 100)
v2 = c(30, 60, 100)

myfun = function(x, y){
  rt = unlist(Vectorize(retimes::rexgauss)(n = x, tau = y, mu = 500, sigma = 50))
  ks = ks.test(rt, "pnorm", mean(rt), sd(rt))$p.value
  shap = shapiro.test(rt)$p.value
  z = skew(rt) / sqrt(6/length(rt))
  ztest = pnorm(-abs(z))*2
  results = c(ks, shap, ztest)
  names(results) = c("ks", "shapiro", "ztest")
  return(results)
}

outer(v1, v2, myfun)

如果我这样做,就会收到此错误:

  

dim(robj)中的错误<-c(dX,dY):昏暗[产品9]与   对象[3]的长度

我想避免循环遍历我的两个向量的所有元素。我在这里如何使用外部功能?如何正确矢量化udf?

1 个答案:

答案 0 :(得分:1)

要使用outer,需要满足一些基本的“要求”:

  1. 该函数将一次获取两个向量(如下所示);是选择对它们进行矢量化工作还是单独对它们进行处理;

  2. 它必须返回与x(和y)长度相同的向量;和

  3. 您必须期望输出为尺寸为matrix的{​​{1}}。

我们继续说明这些并非对您都适用。 “正确的功能”取决于您希望模型如何运行。 length(x),length(y)的伴随函数是outer(和expand.grid,tidyverse版本),因为它会创建所提供矢量的相同组合。例如:

tidyr::crossing

outer(c(30,60,90), c(30, 60, 100), function(x,y) {browser();1;})
# Called from: FUN(X, Y, ...)
# Browse[2]> 
x
# [1] 30 60 90 30 60 90 30 60 90
# Browse[2]> 
y
# [1]  30  30  30  60  60  60 100 100 100

(然后您可以以eg <- expand.grid(x=c(30,60,90), y=c(30, 60, 100)) eg # x y # 1 30 30 # 2 60 30 # 3 90 30 # 4 30 60 # 5 60 60 # 6 90 60 # 7 30 100 # 8 60 100 # 9 90 100 eg$x的身份访问。)

一些选项:

  1. 如果您希望使用两个参数一次调用函数(与eg$y一样),它将找出要执行的操作:

    outer

    请注意,如果给定eg <- expand.grid(x=c(30,60,90), y=c(30, 60, 100)) do.call("myfunc", eg) 参数,则默认情况下(类似于character)将创建data.frame。它确实接受factor参数。

  2. 如果要为每对向量调用函数(在此示例中为9次),则可以选择其中一个

    stringsAsFactors=FALSE

    如果向量数已知。如果不是,则从上方使用myfunc(eg$x, eg$y) ,然后

    eg

    应该工作。根据输出,您可以使用

    来阻止它“简化”输出(即,强制使用do.call("mapply", c(myfunc, eg)) 输出)
    list