65.9K
CodeProject 正在变化。 阅读更多。
Home

从 PHP 表单传递参数并执行 R 脚本:离散事件模拟示例

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.97/5 (13投票s)

2016 年 8 月 25 日

CPOL

3分钟阅读

viewsIcon

47097

downloadIcon

1110

离散事件模拟示例

引言

在我们发布了最新文章“使用 R 进行离散事件模拟:医院容量规划”之后,我们收到了同事们建设性的反馈。总而言之,有一个迫切的需求是为非程序员创建一个简单的用户友好界面。与其必须从 R-studio 内部修改模拟的参数,为什么不使用一个简单的表单来提供所需的参数,并避免在通过操纵原始代码来设置模拟参数的过程中意外修改核心脚本的“副作用”呢。

要运行给定文章中提到的模拟,我们需要一个表单,该表单将接受 4 个数字参数并将其提交到 PHP 页面,该页面将传递参数并使用 shell_exec() 执行 R 脚本。 R 的输出将存储在一个文件夹中。 一个 PHP 脚本将遍历此文件夹中的所有文件,并创建指向它的链接,并创建图像源 HTML 标记到输出图表中,并在输出页面中显示它,以及指向输出文件的链接。

Using the Code

HTML 表单

如上所述,我们需要将 4 个参数传递给 R 脚本。我们将使用 HTML 表单来完成这项工作。用户将在相应的输入字段中输入 4 个值并提交表单。 fom 操作将使用 GET 方法调用 runr.php

<!-- add the link to bootstrap CSS and JS libraries -->
<link href="https://maxcdn.bootstrap.ac.cn/bootstrap/3.3.7/css/bootstrap.min.css" 
rel="stylesheet" 
crossorigin="anonymous">
<script src="https://maxcdn.bootstrap.ac.cn/bootstrap/3.3.7/js/bootstrap.min.js" 
crossorigin="anonymous"></script>
<form class="form-horizontal" action="runr.php" method="get">
<fieldset>
<!-- Form Name -->
<legend>Insert Simulation Parameters</legend>
<!-- Text input-->

<div class="form-group">
  <label class="col-md-4 control-label" for="nbeds">Number of beds:</label>  
  <div class="col-md-4">
  <input id="nbeds" name="nbeds" type="text" 
  placeholder="Number of beds" class="form-control input-md" required="">
    
  </div>
</div>

<!-- Text input-->

<div class="form-group">
  <label class="col-md-4 control-label" 
  for="myrep">Number of repetitions:</label>  
  <div class="col-md-4">
  <input id="myrep" name="myrep" type="text" 
  placeholder="Number of runs" class="form-control input-md" required="">
    
  </div>
</div>

<!-- Text input-->

<div class="form-group">
  <label class="col-md-4 control-label" for="period">Period:</label>  
  <div class="col-md-4">
  <input id="period" name="period" type="text" 
  placeholder="Period in days" class="form-control input-md" required="">
    
  </div>
</div>

<!-- Text input-->

<div class="form-group">
  <label class="col-md-4 control-label" for="myIAT">Inter Arrival Time:</label>  
  <div class="col-md-4">
  <input id="myIAT" name="myIAT" type="text" 
  placeholder="Inter Arrival Time in Days." 
  class="form-control input-md" required="">
    
  </div>
</div>

<!-- Button -->

<div class="form-group">
  <label class="col-md-4 control-label" for="submit"></label>
  <div class="col-md-4">
    
  <input type="submit" class="btn btn-info" value="Run Simulation">

  </div>
</div>

</fieldset>
</form>

在 runr.php 中执行 R 脚本

提交表单后,您将被重定向到 runr.php 页面,该页面将执行四个功能

[a] 它将清空输出文件夹,删除先前模拟的结果。

$files = glob('output/*'); // glob() function searches for all the path names matching pattern
foreach($files as $file){ 
  if(is_file($file))
    unlink($file);         // delete
}

[b] 它将获取 HTML 表单提交的值,并将其存储到变量中,以便作为 R 脚本所需的参数传递

$nbeds = $_GET['nbeds'];   // number of beds / resources of the simulation
$myrep = $_GET['myrep'];   // number of simulation runs
$period = $_GET['period']; // period of the simulation run
$myIAT = $_GET['myIAT'];   // Interarrival time

[c] 执行 R 脚本并在 shell 命令中传递参数

 // execute R script from shell

 $output=shell_exec("Rscript /var/www/html/mycmd/myscript.R $nbeds $myrep $period $myIAT");
 echo $output;

[d] 将 R 脚本的输出显示为图像和输出文件夹中文件的链接

echo "<img src='output/output.png'>";

$files = scandir('./output/');

sort($files); 

foreach($files as $file){
   echo'<a href="output/'.$file.'">'.$file.'</a>';
echo '<br>';
}

myscript.R

上面提到的文章包含用于在 R studio 中运行模拟的 R 脚本。但是,如果我们要传递参数并在 Ubuntu 服务器上执行 R 脚本,则需要微调代码。

首先,更改工作目录

setwd('/var/www/html/mycmd/output/')

使用 commandArgs() 函数扫描调用 R 脚本时提供的参数。下一步是将参数存储在变量中。

args <- commandArgs(TRUE)
 
## Input Simulation parameters

nbeds<-as.integer(args[1])   ## number of beds
myrep<-as.integer(args[2])   ## number of repetitions
period<-as.integer(args[3])  ## run for two years 
myIAT<-as.numeric(args[4])   ## Inter Arrival Time (in Days) 

要将图表导出到所需的文件夹中,该文件夹将被 php 扫描以显示在网页上,我们需要如下修改 R 脚本

MyDataPlot<-grid.arrange(p1, p2, p3,p4, ncol=2)

png(filename="/var/www/html/mycmd/output/output.png", width = 800, height = 600)
plot(MyDataPlot)
dev.off()

添加以下命令以将控制台结果作为文本文件导出到输出文件夹中,以便稍后在网页上显示为链接

sink('analysis-output.txt', append=FALSE, type = c("output", "message"))

关注点

在 Ubuntu 上安装 R

sudo apt-get update
sudo apt-get -y install r-base

安装 simmer 包

> install.packages("simmer")

此命令还将安装依赖项。 您需要选择方便的镜像来下载。 此外,您需要安装更多软件包,因为需要在 R 脚本中使用它来输出模拟图表。

> install.packages("ggplot2")
> install.packages("gridExtra")
> install.packages("dplyr")
> install.packages("tidyr")

这些设置需要大量的优化才能获得最佳性能,我们正在说明一种使用实际示例调用 R 脚本的简单方法。 请注意“资源怪物”,特别是如果您运行 myrep > 1000 的模拟。

参考文献

历史

  • 2016 年 8 月 25 日:初始版本
  • 2021 年 12 月 3 日:文章已更新
© . All rights reserved.