R 扩展:调用包中的外部脚本


R extensions: calling an external script within a package

我正在编写一个R包,其中定义了一个名为PHP脚本包装器的函数。让我们假设 PHP 脚本提供了一些在 R 中很难重新创建的功能,并且我的推理路线(将 PHP 脚本包装在 R 中)是有意义的。

我目前将 PHP 脚本保存在一个单独的文件中,并通过系统调用运行它。

我的 R 函数/包装器如下所示:

wrapper <- function() {
  # I'm not entirely sure what the path to the PHP file should be
  php_file_name <- "magic_in.php"
  php_script_argument <- "hello, world"
  system_call <- sprintf('php -f "%s"', php_file_name, php_script_argument)
  system(system_call)
}

magic_in.php文件如下:

<?php
    print($argv[1]."'n")
?>

但是这个解决方案很糟糕 - 仅当我当前工作目录中有 PHP 脚本时,系统调用才有效。

我将包装器保存在~/simple_package/R/wrapper.R文件中,但我不确定将 PHP 脚本存储在哪里。

我是否应该将PHP文件保存在~/simple_package/src目录中,然后使用一些专用的R函数(例如C可执行文件的.Call函数)调用它?

可能/data不是包脚本的最佳选择,/exec可能是更好的选择。

看:

  • R包"exec"或"tools"目录中是否有任何特殊功能?

您也可以考虑使用system2

  • 系统2在R中运行
  • 在 R 中捕获退出状态和系统调用的输出

对于某些语言(Python),CRAN 中有一些特殊的支持

  • rPython:允许R调用Python的包

一个例子(使用systemsystem.file):

  • http://r.789695.n4.nabble.com/exec-subdirectory-of-a-package-td924560.html

它由外部 R 脚本命令行执行:

#!/bin/env Rscript
args <- commandArgs(TRUE)
if( length(args) < 2 ){
    stop( "usage : R CMD execute package script [parameters]'n" )
}
package <- args[1]
script <- args[2]
scriptfile <- file.path( system.file( "exec", script, package = package ) ) # <= path
if( !file.exists( scriptfile ) ){
    stop( sprintf( "file not found: '%s' ", scriptfile  ) )
}
trail <- if( length(args) > 2 ) paste( tail( args, -2 ), sep = " " ) else ""
cmd <- sprintf( '"%s" %s', scriptfile, trail )
system( cmd ) # <= or system2 ...

有许多方法可以做到这一点。您可以将函数硬编码到脚本中,将其写入文件,通过带有参数wrapper的函数运行它(创建文件时路径是隐式的),然后进行清理。

更好的方法可能是将脚本放入/data并通过 ?system.file 调用它。