我覺得你的問題是,SAS試圖將日誌文件寫入到您沒有寫入權限的目錄。您可以將該日誌文件(和.out文件)的備用位置傳遞給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腳本產生的任何結果相同的位置,而不是在一個不明確的臨時目錄中。
高級示例:
我曾經寫過的包裝功能的SAS腳本,其中包括記錄和錯誤處理。也許這是對你有用,但你將不得不稍作修改,使其在系統上運行:
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)
}
注:
- ,我不得不刪除一些代碼塊包含具體針對我希望我沒有留下任何讓人困惑的項目。
- 我將參數
infile
和outfile
作爲如何將宏變量傳遞給SAS腳本的示例。您可以像這樣在SAS腳本中使用它們:%let fileIn = %sysget(filein)
。
您的代碼是否從命令行工作,即執行SAS代碼的系統命令? – Reeza
您可能希望查看'processx'作爲'system'和'system2'的替代方案 –