使用 shell 函数从 r 运行 sas [英] run sas from r using shell function

查看:88
本文介绍了使用 shell 函数从 r 运行 sas的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我按照 Dominic Comtois 的方法使用 R 执行 sas 程序 (使用 system() 命令在 R 中执行 SAS 程序).当我执行我的测试代码时,出现了错误消息

I am using R to execute a sas program following Dominic Comtois's approach (Executing a SAS program in R using system() Command). When I executed my test codes, a error massage showed up

ERROR: Insufficient authorization to access C:\Program Files\SASHome\x86\SASFoundation\9.3\test_YL.log.

My test sas program was:

   libname XX 'F:/sitetools';
   data XX.test;
   input species $ bec_i_c $ agetype age height;
   cards;
   FD  C 1 35 14.3
   FD  C 0 35 14.3
   FD  I 1 35 14.3
   FD  I 0 35 14.3
   PL  I 1 65 14.3
   PL  I 1 25 14.3
   PL  I 0 65 14.3
   PL  I 0 25 14.3
   ;
   run;

如何解决这个问题.任何帮助将不胜感激.

How to resolve this issue. Any help will be highly appreciated.

推荐答案

我认为您的问题是 SAS 尝试将日志文件写入您没有写入权限的目录.您可以将该日志文件(和 .out 文件)的备用位置传递给 SAS:

I think your problem is that SAS tries to write a logfile to a directory where you have no write access. You can pass an alternate location for that log file (and the .out file) to SAS:

  sas_log <- tempfile()
  sas_out <- tempfile()

  cmd <- sprintf(
    'sas.exe -nosplash -icon -sysin "%s"  -log "%s" -print "%s"',
    sas_script, sas_log, sas_out
  )

 return_code  <- system(cmd)  # Runs sas and saves the return code to 

我认为这应该可以解决您的问题.您可能希望日志文件与 SAS 脚本生成的任何结果位于同一位置,而不是位于模糊的临时目录中.

I think this should solve your problem. You will probably want your log file in the same location as whatever result your SAS script produces, and not in a obscure temporary directory.

高级示例:

我曾经为 SAS 脚本编写了一个包装函数,其中包括日志记录和错误处理.也许这对您有用,但您必须对其进行一些修改才能使其在您的系统上运行:

I once wrote a wrapper function for a SAS script that includes logging and error handling. Maybe this is useful to you, but you will have to modify it a bit to make it run on your system:

library(futile.logger)
library(purrr)
library(assertthat)
library(stringi)
library(magrittr)

sasget <- function(
  infile,
  outfile = NULL,
  sas_script,
  sas_path   = "C:/Program Files/SAS/x86/SASFoundation/9.4",
  sas_config =  "C:/Program Files/SAS/x86/SASFoundation/9.4/nls/de/sasv9.cfg"
){
  # Precondtions
    assert_that(purrr::is_scalar_character(infile))
    assert_that(is.null(outfile) || purrr::is_scalar_character(outfile))
    assert_that(file.exists(sas_script))
    assert_that(dir.exists(sas_path))
    assert_that(file.exists(sas_config))


  # Process arguments
    if(is.null(outfile)) outfile <- tempfile()
    sas_log <- paste0(outfile, '.log')
    sas_out <- paste0(outfile, '.lst')


  # Launch sas job
    owd <- getwd()
    setwd(sas_path)
    on.exit(setwd(owd), add = TRUE)


    cmd <- sprintf(
      'sas.exe -nosplash -icon -sysin "%s" -set filein "%s" -set fileout "%s" -log "%s" -print "%s"',
      sas_script, infile, outfile, sas_log, sas_out)

    flog.debug('Launching SAS job')
    flog.trace(cmd)

    return_code  <- shell(cmd)  # Run SAS and retain return code


  # Process SAS Log
    log <- suppressWarnings(try(readLines(sas_log), silent = TRUE))

    errors <- log %>%
      stringi::stri_subset_regex('^ERROR.*:')
    lapply(log, flog.trace)


  # Postconditions
    ok <- TRUE

    if(!identical(return_code, 0L)){
      flog.error('SAS process returned nonzero return code: %s', return_code)
      ok <- FALSE
    }

    if(isTRUE(file.size(outfile) == 0L)){
      flog.error('SAS process returned empty file')
      ok <- FALSE
    }

    if(length(errors) > 0L){
      lapply(errors, flog.error)
      ok <- FALSE
    }

    if(ok){
      flog.debug('SAS file transfer successful')
    } else {
      flog.fatal('There were Errors, please check SAS log: %s', sas_log) %>%
        stop()
    }


  # output
  res <- outfile
  return(res)
}

注意事项:

  • 我不得不删除一些特定于我正在处理的项目的代码块,我希望我没有留下任何令人困惑的东西.
  • 我留下了参数 infileoutfile 作为如何将宏变量传递给 SAS 脚本的示例.您可以像这样在 SAS 脚本中使用它们:%let fileIn = %sysget(filein).
  • I had to remove some code chunks that were specific to the project I was working on, I hope i didn't leave anything confusing in.
  • I left the parameters infile and outfile in as an example of how to pass macro variables to a SAS script. You can use them in your SAS script like this: %let fileIn = %sysget(filein).

这篇关于使用 shell 函数从 r 运行 sas的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆