Skip to content

Instantly share code, notes, and snippets.

@paulrougieux
Last active August 29, 2015 14:23
Show Gist options
  • Save paulrougieux/b869dbd23a71a788cbaf to your computer and use it in GitHub Desktop.
Save paulrougieux/b869dbd23a71a788cbaf to your computer and use it in GitHub Desktop.
Create and execute an Octave file
#' Create and execute an Octave file
#'
#' This function creates 2 files in the working directory:
#' \itemize{
#' \item{filename.m contains an Octave (Matlab) script}
#' \item{filename.csv contains estimation results}
#' }
#' Variables filename and
#' allitems are currently used as mustache tag variables.
#' More information on the Mustache format:
#' https://github.com/mustache/mustache
#' See source near octavecommand to see how the replacement is done.
#'
#' The output of Octave is sent to filename.log.
#' @param dtf a data frame containing at least an item column
#' @param octavecommand the octave command with optional mustache
#' variables included
#' @param filename the name of the file without extension
#' @param path the path where csv data files are located
#' @param sleep waiting time after calling stata and before reading the csv result file
#' @param nblines number of lines to be expected in the result file
#' @return a dataframe containing estimation results
#' @export
octave <- function(dtf, octavecommand, filename,
path = "data-end/octave/",
sleep = 0.2, nblines = length(unique(dtf$item))){
allitems <- paste0("'", paste(unique(fp$item), collapse = "','"), "'")
resultfile <- paste0(path, filename, ".csv")
if (file.exists(resultfile)){
file.remove(resultfile)
}
### Create an octave ".m" file
octavefile <- file(paste0(path, filename, ".m"), "w")
octavecommand %>%
gsub("\\{\\{filename\\}\\}", filename, .) %>%
gsub("\\{\\{allitems\\}\\}", allitems, .) %>%
cat(file = octavefile)
close(octavefile)
### Execute the octave ".m" file
basedir <- getwd()
setwd(path)
tryCatch(system2("octave",
c(paste0(filename,".m", "&")),
wait = TRUE),
finally = setwd(basedir))
# Didn't mannage to redirect stdout
# stdout = paste0(filename,".log"),
### Read results from the csv file
# Even with system2(wait = TRUE) the file is not created
# before read.csv tries to read it
# Therefore the while() instruction waits "sleep" seconds
# until the result file contains the expected
# number of lines
result <- data.frame()
while(!file.exists(resultfile)) Sys.sleep(sleep)
while(nrow(result) < nblines){
Sys.sleep(sleep)
tryCatch(result <- read.csv(resultfile, na.strings =".", as.is=TRUE),
warning = function(w) {
message(sprintf("Wait %s seconds for Octave to finnish writing csv file.", sleep))})
}
return(result)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment