【问题标题】:randomly select and execute a function from a list. Repeat the process and save the outputs从列表中随机选择并执行一个函数。重复该过程并保存输出
【发布时间】:2017-08-07 09:56:35
【问题描述】:

我有多个生成随机数的函数。所有这些功能都描述了相同的过程。我想随机选择一个函数 100 次,执行它并将结果(每个函数执行 100 行)保存在一个表中。

对于函数我写了如下代码:

# AKBAS u.a. (2009)
akbas <- function(n){
  x.m=se.m=x.st=se.st=NULL 
  for(i in 1:n){
    print(x.m[i] <- runif(n = 1, min = 0, max = 1))
    se.m[i] <- 0.17 * (x.m[i]^2) - 0.03 * x.m[i]
    print(x.st[i] <- runif(n = 1, min = 1, max = 5))
    se.st[i] <- 0.17 * (x.st[i]^2) - 0.03 * x.st[i]
  }
  return(list(se.m, se.st))
}
se.akbas <- matrix(unlist(akbas(100)),100, 2)

# FUCHS u.a.(2007)
fuchs07 <- function(n){
  x.m=se.m=x.st=se.st=NULL #solves indexing problem
  for(i in 1:n){
    print(x.m[i] <- runif(n = 1, min = 0, max = 1))
    se.m[i] <- 0.11 * (x.m[i]^2) - 0.02 * x.m[i]
    print(x.st[i] <- runif(n = 1, min = 1, max = 5))
    se.st[i] <- 0.11 * (x.st[i]^2) - 0.02 * x.st[i]
  }
  return(list(se.m, se.st))
}
se.fuchs07 <- matrix(unlist(fuchs07(100)),100, 2)

# BELL AND GLADE (2004)
bell.glade <- function(n){
  x.m=se.m=x.st=se.st=NULL 
  for(i in 1:n){
    se.m[i] <- runif(n = 1, min = 0, max = 1)
    se.m[i] <- 0.2
    se.st[i] <- runif(n = 1, min = 1, max = 5)
    se.st[i] <- 0.5
  }
  return(list(se.m, se.st))
}
se.bell.glade <- matrix(unlist(bell.glade(100)),100, 2)

# BORTER (1999b,a)
borter <- function(n){
  x.m=se.m=x.st=se.st=NULL 
  for(i in 1:n){
    se.m[i] <- runif(n = 1, min = 0, max = 1)
    se.m[i] <- 0.1
    se.st[i] <- runif(n = 1, min = 1, max = 5)
    se.st[i] <- 0.5
  }
  return(list(se.m, se.st))
}
se.borter <- matrix(unlist(borter(100)),100, 2)

# FELL UND HARTFORD (1997)
fell.hartford <- function(n){
  x.m=se.m=x.st=se.st=NULL 
  for(i in 1:n){
    se.m[i] <- ifelse (runif(n = 1, min = 0, max = 1) < 0.25, 0.1, 0.4)
    se.st[i] <- ifelse (runif(n = 1, min = 1, max = 5) < 1.5, 0.4, 0.7)
  }
  return(list(se.m, se.st))
}
se.fell.hartford <- matrix(unlist(fell.hartford(100)),100, 2)

funktionen <- list(se.akbas, se.bell.glade, se.borter, se.fell.hartford, se.fuchs07)
murgang <- do.call(rbind, funktionen)

最终输出应该是长格式 - se.m 和 se.st 堆叠。我包括一个指标列,其中 se.m 的值为 1,se.st 的值为 2。这里是输出的一小部分:

495           1  0.0228
496           1  0.0494
497           1  0.0158
498           1  0.0169
499           1  0.0357
500           1  0.0436
501           2  0.3459
502           2  2.7998
503           2  3.6571
504           2  3.1501
505           2  2.7418
506           2  0.5286

但是,我被困在随机函数选择get.f 的过程中。我在想类似的东西:

get.f <- function(m){
  sample(funktionen, 100, replace = TRUE)
} 

如何保存结果?

对简化这个过程有什么建议吗?我确信有一种更有效的方法,但我还没有找到它。

我是 R 新手,我会高度评价任何建设性的 cmets 和/或批评。

PS:这可能不是有史以来最好的问题,我知道你给我的评价是-1。但是如果你这样做了,请告诉我为什么,这样我可以改进,以后不会犯同样的错误。

【问题讨论】:

  • 为什么不直接对函数的索引进行采样并按列表中的位置调用它们呢? ss &lt;- sample(length(funktionen),size=100,replace=TRUE); res &lt;- unlist(lapply(ss,function(i) funktionen[[i]](100)) ?

标签: r function random nested simulation


【解决方案1】:

首先是对功能的改进。您不需要 for 循环 1:n 然后设置 runif(n=1...),而只需设置 runif(n...) 其中 n 作为参数提供给您的函数。

您也不需要在函数内列出结果se.mse.st,然后在取消列出并设置为矩阵之后。相反,返回结果的cbind。见下文:

bell.glade <- function(n){
  x.m=se.m=x.st=se.st=NULL 
    se.m <- runif(n, min = 0, max = 1)
    se.st <- runif(n, min = 1, max = 5)
  return(cbind(se.m, se.st))
}
bell.grade(4) # where n=4

其次,我想你忘记删除 bell.gradeborter 中设置的 se.mse.st 中的常量,你可能正在使用它们进行故障排除,我在下面的最终版本中删除了它们。

现在是功能,(我添加了功能名称的打印用于测试):

# AKBAS u.a. (2009)
akbas <- function(n){
  x.m=se.m=x.st=se.st=NULL 
    print(x.m <- runif(n, min = 0, max = 1))
    se.m <- 0.17 * (x.m^2) - 0.03 * x.m
    print(x.st <- runif(n, min = 1, max = 5))
    se.st <- 0.17 * (x.st^2) - 0.03 * x.st
    print("akbas")
  return(cbind(se.m, se.st))
}
# FUCHS u.a.(2007)
fuchs07 <- function(n){
  x.m=se.m=x.st=se.st=NULL #solves indexing problem
    print(x.m <- runif(n, min = 0, max = 1))
    se.m <- 0.11 * (x.m^2) - 0.02 * x.m
    print(x.st <- runif(n, min = 1, max = 5))
    se.st <- 0.11 * (x.st^2) - 0.02 * x.st
    print("fuchs07")
  return(cbind(se.m, se.st))
}
# BELL AND GLADE (2004)
bell.glade <- function(n){
  x.m=se.m=x.st=se.st=NULL 
    se.m <- runif(n, min = 0, max = 1)
    se.st <- runif(n, min = 1, max = 5)
    print("bell.glade")
  return(cbind(se.m, se.st))
}
# BORTER (1999b,a)
borter <- function(n){
  x.m=se.m=x.st=se.st=NULL 
    se.m <- runif(n, min = 0, max = 1)
    se.st <- runif(n, min = 1, max = 5)
    print("borter")
  return(cbind(se.m, se.st))
}
# FELL UND HARTFORD (1997)
fell.hartford <- function(n){
  x.m=se.m=x.st=se.st=NULL 
    se.m <- ifelse (runif(n, min = 0, max = 1) < 0.25, 0.1, 0.4)
    se.st <- ifelse (runif(n, min = 1, max = 5) < 1.5, 0.4, 0.7)
    print("fell.hartford")
  return(cbind(se.m, se.st))
}

这里是函数列表:

funktionen <- list(akbas, bell.glade, borter, fell.hartford, fuchs07)

注意使用do.call访问funktionen中的函数列表,这里我们测试borter

do.call(funktionen[[3]], args=list(n=1)) # borter
[1] "borter"
          se.m    se.st
[1,] 0.7996913 1.505884

现在这意味着funktionen 1:5 的索引需要被采样 100 次才能随机返回对列表中 5 个函数之一的调用 100 次。

fxn_list_sample <- sample(1:5, 100, replace=T)
fxn_list_result <- sapply(fxn_list_sample, function(x) do.call(funktionen[[x]], args=list(n=1)))
fxn_list_result

这会打印被调用的函数的随机序列。 fxn_list_result 返回具有第一行 se.m 值和第二行 se.st 值的 2x100 矩阵。您可以转换为长格式。如有必要,设置种子 set.seed 以实现可重复性。

【讨论】:

  • 谢谢@R.S,这正是我想要的。关于函数,bell.gradeborter 我的意思是在指定的间隔上分配常量。我改进了命令:se.m[i] &lt;- ifelse (runif(n = 1, min = 0, max = 1) &lt; 1, 0.2, 0.2)do.call 函数效果很好。但我不明白为什么 R 将 se.mse.set 更改为 v1v2。有没有办法保留原始名称,还是我需要手动重命名v1v2
  • 我的意思是 se.st 而不是 se.set...我的道歉!
  • @Danka,当 n 是函数的参数时,我不确定为什么要在函数中设置 n=1,例如bell.grade ?ifelse,其中参数定义为ifelse(test, yes, no)。您的测试语句读取 0 和 1 之间的随机统一数是否小于 1,如果是,则使用 0.2,如果不是,则使用 0.2。为什么要使用runif 号码?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多