当前位置: 首页 > 知识库问答 >
问题:

使我的两个不同的R函数成为一个函数

况经纬
2023-03-14

我想在R中的MonteCarlo包中使用MonteCarlo功能,它有一个需求,作为供应MonteCarlo包中的一个功能。

要运行模拟研究,用户必须在一个函数中嵌套这两个函数——生成样本和从该样本计算所需的统计数据。此函数传递给MonteCarlo()。不需要额外的编程(Vignette:MonteCarlo包)。

与这个重要条件相反,我有两个不同的函数适合我的算法。我使用了这个问题的正确答案提供的MonteCarlo函数作为方法。

我想使用不同的方法,因此,我编写了以下函数(函数1和函数2),以便将其传递给MonteCarlo函数,如下所示:

下面是我想用R做的算法:

  1. ARIMA模型到ARIMA模拟10个时间序列数据集。sim()功能

下面的R函数可以实现这一点。

library(MonteCarlo)
library(forecast)
library(Metrics)
############################################
function1 <- function(lb, ov, n) {

  starts <- unique(sort(c(seq(1, n, lb), seq(lb-ov+1, n, lb))))
  ends <- pmin(starts + lb - 1, n)

  # truncate starts and ends to the first num elements
  num <- match(n, ends)
  head(data.frame(starts, ends), num)
}
#############################################
# parameter grids
n <- 10 # length of time series
lb <- seq(n-2) + 1 # vector of block sizes
phi <- 0.6 # autoregressive parameter
reps <- 3 # monte carlo replications

# simulation function  
function2 <- function(n, lb, phi) {

  #### simulate ####
  ov <- ceiling(lb/2)
  vblocks <- Vectorize(function1, c("lb", "ov"), SIMPLIFY = FALSE)
  d <- vblocks(lb = lb, ov = ov, n = n)
  ts <- arima.sim(n, model = list(ar = phi, order = c(1, 0, 0)), sd = 1)

  #### devide ####
  blk <- lapply(d, function(x) with(x, Map(function(i, j) ts[i:j], starts, ends)))
  #### resample ####
  res <- sample(blk, replace = TRUE, 10)        # resamples the blocks
  res.unlist <- unlist(res, use.names = FALSE)   # unlist the bootstrap series
  #### train, forecast ####
  train <- head(res.unlist, round(length(res.unlist) - 10)) # train set
  test <- tail(res.unlist, length(res.unlist) - length(train)) # test set
  nfuture <- forecast(train, # forecast
                      model = auto.arima(train), 
                      lambda = 0, biasadj = TRUE, h = length(test))$mean    
  ### metric ####
  RMSE <- rmse(test, nfuture) # return RMSE
  return(
    list("RMSE" = RMSE)
  )
}

param_list = list("n" = n, "lb" = lb, "phi" = phi)

set.seed(123, kind = "L'Ecuyer-CMRG")
MC_result <- MonteCarlo(func = bootstrap4, 
                            nrep = reps,
                            ncpus = parallel::detectCores() - 1,
                            param_list = param_list,
                            export_also = list(
                              "packages" = c("forecast", "Metrics")
                            ),
                            raw = T)

我在运行上述操作时出现了以下错误:

在snowfall::sfExport(“func2”、“func”、“libloc_strings”、“function1”中):未知/未找到的变量以export结尾。(local=TRUE)

我想将function1集成到function2中,使function1不再是function2中的函数。

这是我的审判

function2 <- function(n, lb, phi) {

  #### simulate ####
  ov <- ceiling(lb/2)
  function1 <- head(data.frame(unique(sort(c(seq(1, n, lb), seq(lb-ov+1, n, lb)))), pmin(unique(sort(c(seq(1, n, lb), seq(lb-ov+1, n, lb)))) + lb - 1, n)), match(n, pmin(unique(sort(c(seq(1, n, lb), seq(lb-ov+1, n, lb)))) + lb - 1, n)))
  vblocks <- Vectorize(function1, c("lb", "ov"), SIMPLIFY = FALSE)
  d <- vblocks(lb = lb, ov = ov, n = n)
  ts <- arima.sim(n, model = list(ar = phi, order = c(1, 0, 0)), sd = 1)

  #### devide ####
    blk <- lapply(d, function(x) with(x, Map(function(i, j) ts[i:j], unique(sort(c(seq(1, n, lb), seq(lb-ov+1, n, lb)))), pmin(unique(sort(c(seq(1, n, lb), seq(lb-ov+1, n, lb)))) + lb - 1, n))))

  #### resample ####
  res <- sample(blk, replace = TRUE, 10)        # resamples the blocks
  res.unlist <- unlist(res, use.names = FALSE)   # unlist the bootstrap series
  #### train, forecast ####
  train <- head(res.unlist, round(length(res.unlist) - 10)) # train set
  test <- tail(res.unlist, length(res.unlist) - length(train)) # test set
  nfuture <- forecast(train, # forecast
                      model = auto.arima(train), 
                      lambda = 0, biasadj = TRUE, h = length(test))$mean    
  ### metric ####
  RMSE <- rmse(test, nfuture) # return RMSE
  return(
    list("RMSE" = RMSE)
  )
}

当我把它传给这个:

set.seed(123, kind = "L'Ecuyer-CMRG")
MC_result <- MonteCarlo(func = function2, 
                            nrep = reps,
                            ncpus = parallel::detectCores() - 1,
                            param_list = param_list,
                            export_also = list(
                              "packages" = c("forecast", "Metrics")
                            ),
                            raw = T)

我收到了这个错误信息:

3个节点产生错误;第一个错误:找不到函数"vblock"

我在试验中所做的只是将整个function1作为一条语句放入function2


共有1个答案

许振海
2023-03-14

您可以将function1的内容放入function2的主体中,包括变量赋值等。

library(MonteCarlo)
library(forecast)
library(ModelMetrics)

mc_f <- function(n, lb, phi) {
  # Generate data
  ov <- ceiling(lb / 2)
  starts <- unique(sort(c(seq(1, n, lb), seq(lb - ov + 1, n, lb))))
  ends <- pmin(starts + lb - 1, n)
  num <- match(n, ends)
  d <- head(data.frame(starts, ends), num)
  
  ts <- arima.sim(n, model = list(ar = phi, order = c(1, 0, 0)), sd = 1)
  
  blk <- mapply(
    function(start, end) ts[start:end],
    d$starts, 
    d$ends, 
    SIMPLIFY = FALSE
  )
  
  # Resample
  res <- sample(blk, replace = TRUE, 10)
  res.unlist <- unlist(res, use.names = FALSE)
  
  # Train and forecast
  train <- head(res.unlist, round(length(res.unlist) - 10))
  test <- tail(res.unlist, length(res.unlist) - length(train))
  nfuture <- forecast(train,
                      model = auto.arima(train),
                      lambda = 0, biasadj = TRUE, h = length(test))$mean
  
  # Extract metric
  RMSE <- rmse(test, nfuture)
  list("RMSE" = RMSE)
}
reps <- 3
param_list <- list(n = 10, lb = seq(n - 2) + 1, phi = 0.6)

mc_result <- MonteCarlo(
  func = mc_f,
  nrep = reps,
  ncpus = parallel::detectCores() - 1,
  param_list = param_list
)
#> Grid of  8  parameter constellations to be evaluated. 
#>  
#> Simulation parallelized using 3 cpus. 
#>  
#> Progress: 
#>  
#>   |==================================================================================| 100%
 类似资料:
  • 在前面的回答中,Petr Pudlak定义了类,用于不同于从Hask到Hask的函数。使用类型族重写它,它看起来像 在范畴理论中,每当F:c-->D是函子,而G:d-->E是函子时,那么组成GF:c-->E也是函子。 我想用哈斯克尔来表达这一点。由于我不能编写,我引入了一个包装类: 在编写实例时,我得到了以下内容

  • 我想为不同的df-id应用一个函数,如果下一行不同于前一行,则返回1,否则返回0。 我完全不知道我该如何实现这一目标,无论如何都可以完成它吗? 数据结构如下: 预期输出应如下所示:

  • 我有一个Card类,它包含两个构造函数,你可以在下面的代码中看到。问题是,每个卡片对象包含2个字符串和2个图像,因为我想保存这些对象,所以我必须将图像的路径保存为字符串,然后检索它们,因此需要2个构造函数。然而,使用一些打印语句,我发现每当检索到一张卡片时,就会创建两个独立的对象:一个正常的对象和另一个空的对象。我知道这是因为我在第二张卡中使用第一个构造器创建了一张新卡。有没有办法避免这样的情况,

  • 我有两个具有经度和纬度值的数据帧,我想从数据帧#2中提取值(例如数据帧#2的第三列),这些值与数据帧1的列匹配...例如,数据帧1有两列(、),数据帧2有三列(、和一些值)...我想在数据帧1中添加第三列,其中的值对应于两个数据帧中两列完全匹配的值,类似于和...在、不匹配的对中,我希望添加,以便第三列(我要添加到数据。帧1)的长度为=。我尝试了merge函数,但在将的两列与的列进行匹配时遇到了困

  • 问题内容: 我正在使用带有ES6的ReactJS,但是在通过props交流child> parent时遇到一些问题。我的方法示例: 这返回。 任何想法?绑定也许? [编辑]解决方案(感谢@knowbody和@Felipe Skinner): 我在构造函数中缺少绑定。在SearchBar构造函数中的绑定可以完美地工作。 使用(ES5),它会自动为您的功能进行绑定。在ES6中,您需要手动绑定。更多信息

  • 我的问题是关于OOP(C)中的构造函数。当我在一个类中将默认构造函数定义为private,并且在main中将该类的一个对象初始化为default时,就会出现默认构造函数不可访问的错误。这很好。但我也在Public部分中使用默认参数构造函数,当我再次在main中初始化对象时,就会出现对函数重载的不明确调用。所以我的问题是,如果不能从main访问私有构造函数,那么编译器应该调用公共部分中的构造函数,这