我想将用户定义的函数与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?
答案 0 :(得分:1)
要使用outer
,需要满足一些基本的“要求”:
该函数将一次获取两个向量(如下所示);是选择对它们进行矢量化工作还是单独对它们进行处理;
它必须返回与x
(和y
)长度相同的向量;和
您必须期望输出为尺寸为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
的身份访问。)
一些选项:
如果您希望使用两个参数一次调用函数(与eg$y
一样),它将找出要执行的操作:
outer
请注意,如果给定eg <- expand.grid(x=c(30,60,90), y=c(30, 60, 100))
do.call("myfunc", eg)
参数,则默认情况下(类似于character
)将创建data.frame
。它确实接受factor
参数。
如果要为每对向量调用函数(在此示例中为9次),则可以选择其中一个
stringsAsFactors=FALSE
如果向量数已知。如果不是,则从上方使用myfunc(eg$x, eg$y)
,然后
eg
应该工作。根据输出,您可以使用
来阻止它“简化”输出(即,强制使用do.call("mapply", c(myfunc, eg))
输出)
list