Использование mapply внутри функции (...)
Я пытаюсь сгенерировать несколько серий случайных чисел, каждая серия с разным набором параметров. Тогда я хочу повторить все это. Я хочу иметь функцию для этого, и кажется, что это должен быть 1-лайнер с чем-то вроде rnorm()
генерировать числа, mapply()
генерировать эти числа для нескольких наборов параметров, и replicate()
повторить весь процесс.
Чтобы добиться этого, я написал функцию, ...
аргументы, которые я хочу соответствовать ...
в mapply
, но похоже, что ...
игнорируется mapply
, У меня есть несколько примеров, которые должны прояснить мой желаемый результат, а также проблему:
# Some values to be passed to the ... of mapply
mus <- c(-30, 0, 30)
sds <- c(0.1, 1, 10)
# =================================
# = What I want, if it would work =
# =================================
f <- function(n=3, ...){
replicate(2, mapply(rnorm, MoreArgs=list(n=n), ...))
}
f(mean=mus, sd=sds) # Doesn't work :(
>, , 1
>
> [,1]
>[1,] -0.4901243
>[2,] 0.8268027
>[3,] -0.4829781
>
>, , 2
>
> [,1]
>[1,] -0.02025903
>[2,] -1.57011537
>[3,] 0.49234503
# ==========================================================
# = What I can currently get to work, but not style I want =
# ==========================================================
# I can't understand why f.inside is needed!
f2 <- function(n=3, ...){
f.inside <- function() mapply(rand.gen, MoreArgs=list(n=n), ...)
replicate(2, f.inside())
}
f2(mean=mus, sd=sds) # Desired output
>, , 1
>
> [,1] [,2] [,3]
>[1,] -29.83762 -0.06138165 9.956601
>[2,] -30.04880 1.39123405 33.036675
>[3,] -29.94070 -1.15741513 19.337497
>[4,] -29.92360 0.74300731 38.741367
>[5,] -29.81723 0.84565813 22.261605
>
>, , 2
>
> [,1] [,2] [,3]
>[1,] -30.01407 -0.5198845 20.85942
>[2,] -29.77586 -0.1705062 22.06274
>[3,] -29.96901 -0.4412471 21.42849
>[4,] -30.04079 0.4230790 28.35480
>[5,] -30.04794 0.3000821 50.09012
Я думаю, мне нужно обернуть ...
в чем-то; Я случайно попробовал такие вещи, как alist()
, list()
, bquote()
, expression()
, as.call()
и несколько других неудачных подходов.
1) Почему mapply
в f()
кажется, полностью игнорировать ...
? РЕДАКТИРОВАТЬ: Это был вспомогательный вопрос, на который ответ "точки не работают с копией". Хорошо, к основному вопросу...
# =====================================
# = OK, Function for Refined Question =
# =====================================
f.edit <- function(n=3, ...){
l <- list(...)
replicate(2,mapply(rnorm, MoreArgs=list(n=n), l))
}
f.edit(mean=mus, sd=sds) # Doesn't work :(
2) Как разделить элементы объекта на элементы длины (объекта) и передать их как отдельные элементы mapply
"s ...
?
Мне нужно поправиться в моих эллипсах. Я действительно озадачен этим.
2 ответа
В моде вы пытаетесь в f.edit
...
Вы можете построить список аргументов и выполнить
do.call
сmapply
function(n=3, ...){ dots<-list(...); replicate(2,do.call(mapply,c(list(FUN=rnorm),dots,list(MoreArgs=list(n=n))))) }
Или извлеките аргументы и позвоните напрямую
function(n=3, ...){ dots<-list(...); replicate(2,mapply(rnorm,dots$mean,dots$sd,MoreArgs=list(n=n))) }
В любом случае вы заставляете оценку ...
в правильной среде, как это делается в вашем f2
и альтернатива MrFlick.
Проблема с f.edit
как написано rnorm
называется как rnorm(n,list(means=mus,sd=sds))
скорее, чем rnorm(n,means=mu,sd=sds)
,
Однако в этом случае вы можете рассмотреть возможность использования того факта, что rnorm
уже векторизован по своим средним и аргументам sd
function(n,reps,mean,sd) {
m<-length(mean);
aperm(array(rnorm(n*m*reps,mean,sd),c(m,n,reps)),c(2,1,3))
}
Проблема в том, что вы не можете использовать ...
с replicate
как уже обсуждалось здесь.
Я уже думаю, что вы нашли наиболее читаемую альтернативу с помощью вспомогательной функции f.inside()
схватить ...
термины.
Еще один вариант, чтобы избежать replicate
и использовать lapply
(со значениями индекса, которые вы в конечном итоге игнорируете)
f3 <- function(n=3, ...){
lapply(1:2, function(i, ...) mapply(rnorm, MoreArgs=list(n=n), ...), ...)
}
f3(mean=mus, sd=sds)