Как кодировать кусочную функцию в R для небольшой симуляции и сохранять значения во фрейме данных
Мне нужно поместить в код кусочную функцию и сохранить сгенерированные значения во фрейме данных. Правила следующие:
- У меня есть объект X, который генерируется Бернулли (1/3).
- Если X=0, другой объект, Y, генерируется E = Exponential(1).
- Если X=1, Y генерируется E, если E <= P, и (P + EL), если E > P, где P - постоянная (например, 1), а EL = экспоненциальная (лямбда), независимая от E.
- Я хочу сгенерировать кадр данных со 100 выборками X и Y, полученными с использованием этого метода, и дополнительно выполнить этот процесс 10000 раз (или, другими словами, сгенерировать 10000 кадров данных).
Я пытался сделать что-то подобное, но, поскольку я абсолютный новичок, использующий R, я не мог понять, как правильно определить каждый элемент и, очевидно, как сохранить свои результаты в кадре данных.
Вот код, который я сделал:
test <- function(lambda,p) {
for (i in 1:10000) { # Number of simulations that I want to do.
for(j in 1:100) { # Sample size of each simulation / data frame.
x <- rbinom(1,1,1/3)
e <- rexp(1,1)
if (x==0) {y <- e}
else {
if (e<=p) {y <- e}
else {y <- p + rexp(1, lambda)}
}
}
}
Но даже до тестирования я знаю, что это не работает должным образом. Фрейм данных, который я хочу создать, может содержать значения для X и Y.
Я знаю, что это может быть очень простой вопрос, поэтому большое спасибо за ваши ответы.
1 ответ
Решение
Я думаю:
simfun <- function(n=100,lambda=1,P=1,ret.df=TRUE) {
X <- rbinom(n,prob=1/3,size=1)
E <- rexp(n,1)
EL <- rexp(n,lambda)
Y <- ifelse(X==0,E,
ifelse(E<=P,E,P+E*EL))
## return data frame or matrix
if (ret.df) data.frame(X,Y) else cbind(X,Y)
}
system.time(res <- replicate(1e4,simfun(),simplify=FALSE))
## 6 seconds
## or:
library(plyr)
system.time(res2 <- raply(1e4,simfun(ret.df=FALSE),.progress="text")
## returns a 1e4 x 100 x 2 array, maybe more convenient: use
## rlply instead of raply (and ret.df=TRUE) to match the previous
## results