From dd00f51db84b83ea83451bef736397c40fb45796 Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Thu, 4 Nov 2021 12:30:39 -0700 Subject: [PATCH 01/38] use foreign if stata v <= 7 --- R/stata.R | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/R/stata.R b/R/stata.R index 7487214..105b8e5 100644 --- a/R/stata.R +++ b/R/stata.R @@ -102,9 +102,10 @@ stata <- function(src = stop("At least 'src' must be specified"), ## Windows/Stata8 unhappy? dtaInFile <- "RStataDataIn.dta" on.exit(unlink(dtaInFile), add = TRUE) - foreign::write.dta(data.in, + if (stataVersion <= 7) { + foreign::write.dta(data.in, file = dtaInFile, - version = if (stataVersion >= 7) 7L else 6L, + version = 6L, ...) } From 221048b280e0c386a0ef8bd76aa7072aaddec367 Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Thu, 4 Nov 2021 12:31:13 -0700 Subject: [PATCH 02/38] use haven if stata v >= 8 --- R/stata.R | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/R/stata.R b/R/stata.R index 105b8e5..f9ddf96 100644 --- a/R/stata.R +++ b/R/stata.R @@ -107,6 +107,12 @@ stata <- function(src = stop("At least 'src' must be specified"), file = dtaInFile, version = 6L, ...) + } else { + haven_stata_version = if (stataVersion > 15) 15L else stataVersion + haven::write_dta( + data.in, path = dtaInFile, version = haven_stata_version, ... + ) + } } if (dataOut) { From f8debc059dd5ef53406b80d162f5ff43aec9d908 Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Thu, 4 Nov 2021 12:32:02 -0700 Subject: [PATCH 03/38] write w/ foreign for stata v <= 7 --- R/stata.R | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/R/stata.R b/R/stata.R index f9ddf96..f348777 100644 --- a/R/stata.R +++ b/R/stata.R @@ -202,8 +202,9 @@ stata <- function(src = stop("At least 'src' must be specified"), ## Get data outputted ## ------------------ if (dataOut){ + if (stataVersion <= 7) { res <- foreign::read.dta(dtaOutFile, ...) - invisible(res) + invisible(res) } } From daedb5496c4cc01c7f64e7935b90c2cf4edf4b09 Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Thu, 4 Nov 2021 12:32:38 -0700 Subject: [PATCH 04/38] write w/ haven for stata v >= 8 --- R/stata.R | 3 +++ 1 file changed, 3 insertions(+) diff --git a/R/stata.R b/R/stata.R index f348777..22cb2b4 100644 --- a/R/stata.R +++ b/R/stata.R @@ -204,6 +204,9 @@ stata <- function(src = stop("At least 'src' must be specified"), if (dataOut){ if (stataVersion <= 7) { res <- foreign::read.dta(dtaOutFile, ...) + } else { + res <- haven::read_dta(dtaOutFile, ...) + } invisible(res) } From 17422e4f6de9b53cab1acbca02fbf847a17de762 Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Thu, 4 Nov 2021 12:33:07 -0700 Subject: [PATCH 05/38] make saveold optional --- R/stata.R | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/R/stata.R b/R/stata.R index 22cb2b4..03fad95 100644 --- a/R/stata.R +++ b/R/stata.R @@ -45,6 +45,7 @@ stata <- function(src = stop("At least 'src' must be specified"), data.in = NULL, data.out = FALSE, + saveold = FALSE, stata.path = getOption("RStata.StataPath", stop("You need to set up a Stata path; ?chooseStataBin")), stata.version = getOption("RStata.StataVersion", stop("You need to specify your Stata version")), stata.echo = getOption("RStata.StataEcho", TRUE), @@ -154,9 +155,9 @@ stata <- function(src = stop("At least 'src' must be specified"), ## foreign::read.dta() read compatibility if (dataOut){ save_cmd <- sprintf("%s %s%s", - if (stataVersion >= 13) "saveold" else "save", + if (stataVersion >= 13 & saveold) "saveold" else "save", tools::file_path_sans_ext(dtaOutFile), - if (stataVersion >= 14) ", version(12)" else "") + if (stataVersion >= 14 & saveold) ", version(12)" else "") SRC <- c(SRC, save_cmd) } From 69908283640358eb7831d5e98283cbec3a618ef2 Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Thu, 4 Nov 2021 12:33:32 -0700 Subject: [PATCH 06/38] update docs --- R/stata.R | 12 +++++++++--- man/stata.Rd | 14 +++++++++++--- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/R/stata.R b/R/stata.R index 03fad95..13b540c 100644 --- a/R/stata.R +++ b/R/stata.R @@ -1,15 +1,21 @@ #' Send commands to a Stata process #' #' Function that sends commands to a Stata process. -#' @param src character vector of length 1 (path to \code{.do} file) or more -#' (a set of stata commands). See examples. +#' +#' It uses \code{\link[haven]{haven}} for Stata version 8 and beyond, and uses +#' \code{foreign} for Stata version 7 and prior. +#' +#' @param src character vector of length 1 (path to \code{.do} file) or more (a +#' set of stata commands). See examples. #' @param data.in \code{\link{data.frame}} to be passed to Stata #' @param data.out logical value. If \code{TRUE}, the data at the end of #' the Stata command are returned to R. +#' @param saveold logical value.If returning data to R and using Stata version 13+, use +#' saveold in Stata to save dataset. Defaults to FALSE. #' @param stata.path Stata command to be used #' @param stata.version Version of Stata used #' @param stata.echo logical value. If \code{TRUE} stata text output will be printed -#' @param ... parameter passed to \code{\link{write.dta}} +#' @param ... parameter passed to \code{\link{write_dta}} or \code{\link{write.dta}} #' @examples #' \dontrun{ #' ## Single command diff --git a/man/stata.Rd b/man/stata.Rd index b534fa8..9f53006 100644 --- a/man/stata.Rd +++ b/man/stata.Rd @@ -8,6 +8,7 @@ stata( src = stop("At least 'src' must be specified"), data.in = NULL, data.out = FALSE, + saveold = FALSE, stata.path = getOption("RStata.StataPath", stop("You need to set up a Stata path; ?chooseStataBin")), stata.version = getOption("RStata.StataVersion", @@ -17,25 +18,32 @@ stata( ) } \arguments{ -\item{src}{character vector of length 1 (path to \code{.do} file) or more -(a set of stata commands). See examples.} +\item{src}{character vector of length 1 (path to \code{.do} file) or more (a +set of stata commands). See examples.} \item{data.in}{\code{\link{data.frame}} to be passed to Stata} \item{data.out}{logical value. If \code{TRUE}, the data at the end of the Stata command are returned to R.} +\item{saveold}{logical value.If returning data to R and using Stata version 13+, use +saveold in Stata to save dataset. Defaults to FALSE.} + \item{stata.path}{Stata command to be used} \item{stata.version}{Version of Stata used} \item{stata.echo}{logical value. If \code{TRUE} stata text output will be printed} -\item{...}{parameter passed to \code{\link{write.dta}}} +\item{...}{parameter passed to \code{\link{write_dta}} or \code{\link{write.dta}}} } \description{ Function that sends commands to a Stata process. } +\details{ +It uses \code{\link[haven]{haven}} for Stata version 8 and beyond, and uses +\code{foreign} for Stata version 7 and prior. +} \examples{ \dontrun{ ## Single command From 91fa0c1c41074a58eef703f35960214c8380ba05 Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Thu, 4 Nov 2021 12:34:03 -0700 Subject: [PATCH 07/38] import haven --- DESCRIPTION | 1 + 1 file changed, 1 insertion(+) diff --git a/DESCRIPTION b/DESCRIPTION index 8a0bfa3..7137b8b 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -9,6 +9,7 @@ URL: https://github.com/lbraglia/RStata BugReports: https://github.com/lbraglia/RStata/issues Imports: foreign, + haven, tools, utils License: GPL-3 From 9a2817c76ace655025140739399196a2bcf962cb Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Thu, 4 Nov 2021 12:34:28 -0700 Subject: [PATCH 08/38] roxygen version bump --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 7137b8b..a61a657 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -13,5 +13,5 @@ Imports: tools, utils License: GPL-3 -RoxygenNote: 7.1.1 +RoxygenNote: 7.1.2 Encoding: UTF-8 From 23e96390da4421f864d3d6ae9b3c5b378a79437d Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Thu, 4 Nov 2021 12:35:08 -0700 Subject: [PATCH 09/38] rstudio helper files --- .Rbuildignore | 2 ++ .gitignore | 4 ++++ RStata.Rproj | 19 +++++++++++++++++++ 3 files changed, 25 insertions(+) create mode 100644 .gitignore create mode 100644 RStata.Rproj diff --git a/.Rbuildignore b/.Rbuildignore index b77148a..1b86c81 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -1 +1,3 @@ ^\.travis\.yml +^.*\.Rproj$ +^\.Rproj\.user$ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5b6a065 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.Rproj.user +.Rhistory +.RData +.Ruserdata diff --git a/RStata.Rproj b/RStata.Rproj new file mode 100644 index 0000000..8de5cfd --- /dev/null +++ b/RStata.Rproj @@ -0,0 +1,19 @@ +Version: 1.0 + +RestoreWorkspace: Default +SaveWorkspace: Default +AlwaysSaveHistory: Default + +EnableCodeIndexing: Yes +UseSpacesForTab: Yes +NumSpacesForTab: 2 +Encoding: UTF-8 + +RnwWeave: Sweave +LaTeX: pdfLaTeX + +AutoAppendNewline: Yes + +BuildType: Package +PackageUseDevtools: Yes +PackageInstallArgs: --no-multiarch --with-keep.source From 8683eb2162d1d6ef828a444c798d7b016fa4a135 Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Thu, 4 Nov 2021 12:35:31 -0700 Subject: [PATCH 10/38] bump version --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index a61a657..f897dfc 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: RStata Title: A Bit of Glue Between R and Stata -Version: 1.1.1 +Version: 1.2.0 Authors@R: person("Luca", "Braglia", email = "lbraglia@gmail.com", role = c("aut", "cre")) Description: A simple R -> Stata interface allowing the user to execute Stata commands (both inline and from a .do file) From 4acbc8a85ed7452659791f103bb023ecc03e6448 Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Fri, 27 Jan 2023 13:44:36 -0800 Subject: [PATCH 11/38] add readstata13 support --- DESCRIPTION | 3 ++- R/stata.R | 67 +++++++++++++++++++++++++++++++++++++++------------- man/stata.Rd | 23 ++++++++++-------- 3 files changed, 65 insertions(+), 28 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index f897dfc..bdd8ecc 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -10,8 +10,9 @@ BugReports: https://github.com/lbraglia/RStata/issues Imports: foreign, haven, + readstata13, tools, utils License: GPL-3 -RoxygenNote: 7.1.2 +RoxygenNote: 7.2.0 Encoding: UTF-8 diff --git a/R/stata.R b/R/stata.R index 13b540c..7567d4d 100644 --- a/R/stata.R +++ b/R/stata.R @@ -1,21 +1,36 @@ #' Send commands to a Stata process #' #' Function that sends commands to a Stata process. +#' @param src character vector of length 1 (path to \code{.do} file) or more +#' (a set of stata commands). See examples. +#' @param data.in \code{\link{data.frame}} to be passed to Stata +#' @param data.out logical value. If \code{TRUE}, the data at the end of +#' the Stata command are returned to R. +#' @param stata.path Stata command to be used +#' @param stata.version Version of Stata used +#' @param stata.echo logical value. If \code{TRUE} stata text output will be printed +#' @param ... parameter passed to \code{\link{write.dta}} #' -#' It uses \code{\link[haven]{haven}} for Stata version 8 and beyond, and uses -#' \code{foreign} for Stata version 7 and prior. +#' It uses \code{\link[haven]{haven}} (default) or +#' \code{\link[readstata13]{readstata13}} for Stata version 8 and beyond, and +#' uses \code{foreign} for Stata version 7 and prior. #' #' @param src character vector of length 1 (path to \code{.do} file) or more (a #' set of stata commands). See examples. #' @param data.in \code{\link{data.frame}} to be passed to Stata -#' @param data.out logical value. If \code{TRUE}, the data at the end of -#' the Stata command are returned to R. -#' @param saveold logical value.If returning data to R and using Stata version 13+, use -#' saveold in Stata to save dataset. Defaults to FALSE. +#' @param data.out logical value. If \code{TRUE}, the data at the end of the +#' Stata command are returned to R. +#' @param saveold logical value.If returning data to R and using Stata version +#' 13+, use saveold in Stata to save dataset. Defaults to FALSE. +#' @param package character string. R package to use to read/write Stata +#' datasets for Stata versions 8 and beyond. can either be \code{"haven"} or +#' \code{"readstata13"}. defaults to \code{"haven"}. #' @param stata.path Stata command to be used #' @param stata.version Version of Stata used -#' @param stata.echo logical value. If \code{TRUE} stata text output will be printed -#' @param ... parameter passed to \code{\link{write_dta}} or \code{\link{write.dta}} +#' @param stata.echo logical value. If \code{TRUE} stata text output will be +#' printed +#' @param ... parameter passed to \code{\link{write_dta}} or +#' \code{\link{write.dta}} #' @examples #' \dontrun{ #' ## Single command @@ -51,7 +66,9 @@ stata <- function(src = stop("At least 'src' must be specified"), data.in = NULL, data.out = FALSE, + saveold = FALSE, + package = "haven", stata.path = getOption("RStata.StataPath", stop("You need to set up a Stata path; ?chooseStataBin")), stata.version = getOption("RStata.StataVersion", stop("You need to specify your Stata version")), stata.echo = getOption("RStata.StataEcho", TRUE), @@ -75,6 +92,9 @@ stata <- function(src = stop("At least 'src' must be specified"), if (!is.logical(stata.echo)) stop("stata.echo must be logical") + + if (!package %in% c("haven", "readstata13")) + stop("package must be either 'haven' or 'readstata13'") OS <- Sys.info()["sysname"] OS.type <- .Platform$OS.type @@ -115,10 +135,19 @@ stata <- function(src = stop("At least 'src' must be specified"), version = 6L, ...) } else { - haven_stata_version = if (stataVersion > 15) 15L else stataVersion - haven::write_dta( - data.in, path = dtaInFile, version = haven_stata_version, ... - ) + package_stata_version = if (stataVersion > 15) 15L else stataVersion + + if (package == "haven") { + haven::write_dta( + data.in, path = dtaInFile, version = package_stata_version, ... + ) + } + + if (package == "readstata13") { + readstata13::save.dta13( + data.in, file = dtaInFile, version = package_stata_version, ... + ) + } } } @@ -161,9 +190,9 @@ stata <- function(src = stop("At least 'src' must be specified"), ## foreign::read.dta() read compatibility if (dataOut){ save_cmd <- sprintf("%s %s%s", - if (stataVersion >= 13 & saveold) "saveold" else "save", + if (stataVersion >= 13) "saveold" else "save", tools::file_path_sans_ext(dtaOutFile), - if (stataVersion >= 14 & saveold) ", version(12)" else "") + if (stataVersion >= 14) ", version(12)" else "") SRC <- c(SRC, save_cmd) } @@ -208,13 +237,17 @@ stata <- function(src = stop("At least 'src' must be specified"), ## ------------------ ## Get data outputted ## ------------------ - if (dataOut){ + if (dataOut) { if (stataVersion <= 7) { res <- foreign::read.dta(dtaOutFile, ...) - } else { + } + else if (package == "haven") { res <- haven::read_dta(dtaOutFile, ...) } + else if (package == "readstata13") { + res <- readstata13::read.dta13(dtaOutFile, ...) + } + invisible(res) } - } diff --git a/man/stata.Rd b/man/stata.Rd index 9f53006..c04db2f 100644 --- a/man/stata.Rd +++ b/man/stata.Rd @@ -9,6 +9,7 @@ stata( data.in = NULL, data.out = FALSE, saveold = FALSE, + package = "haven", stata.path = getOption("RStata.StataPath", stop("You need to set up a Stata path; ?chooseStataBin")), stata.version = getOption("RStata.StataVersion", @@ -23,27 +24,29 @@ set of stata commands). See examples.} \item{data.in}{\code{\link{data.frame}} to be passed to Stata} -\item{data.out}{logical value. If \code{TRUE}, the data at the end of -the Stata command are returned to R.} +\item{data.out}{logical value. If \code{TRUE}, the data at the end of the +Stata command are returned to R.} -\item{saveold}{logical value.If returning data to R and using Stata version 13+, use -saveold in Stata to save dataset. Defaults to FALSE.} +\item{saveold}{logical value.If returning data to R and using Stata version +13+, use saveold in Stata to save dataset. Defaults to FALSE.} + +\item{package}{character string. R package to use to read/write Stata +datasets for Stata versions 8 and beyond. can either be \code{"haven"} or +\code{"readstata13"}. defaults to \code{"haven"}.} \item{stata.path}{Stata command to be used} \item{stata.version}{Version of Stata used} -\item{stata.echo}{logical value. If \code{TRUE} stata text output will be printed} +\item{stata.echo}{logical value. If \code{TRUE} stata text output will be +printed} -\item{...}{parameter passed to \code{\link{write_dta}} or \code{\link{write.dta}}} +\item{...}{parameter passed to \code{\link{write_dta}} or +\code{\link{write.dta}}} } \description{ Function that sends commands to a Stata process. } -\details{ -It uses \code{\link[haven]{haven}} for Stata version 8 and beyond, and uses -\code{foreign} for Stata version 7 and prior. -} \examples{ \dontrun{ ## Single command From ca7d2d90b5ef331854b05e37891734f44c8bcbb1 Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Fri, 27 Jan 2023 13:44:55 -0800 Subject: [PATCH 12/38] update authors and maintainers --- DESCRIPTION | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index bdd8ecc..5433bc6 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,9 @@ Package: RStata Title: A Bit of Glue Between R and Stata Version: 1.2.0 -Authors@R: person("Luca", "Braglia", email = "lbraglia@gmail.com", role = c("aut", "cre")) +Authors@R: c( + person("Eve", "Perry", email = "eve@eveperry.com", role = c("aut", "cre")), + person("Luca", "Braglia", email = "lbraglia@gmail.com", role = "aut")) Description: A simple R -> Stata interface allowing the user to execute Stata commands (both inline and from a .do file) from R. From 75912b6371961af45f6b1dc760ca493b49d75eb0 Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Fri, 27 Jan 2023 13:45:01 -0800 Subject: [PATCH 13/38] update urls --- DESCRIPTION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 5433bc6..ca9439b 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -7,8 +7,8 @@ Authors@R: c( Description: A simple R -> Stata interface allowing the user to execute Stata commands (both inline and from a .do file) from R. -URL: https://github.com/lbraglia/RStata -BugReports: https://github.com/lbraglia/RStata/issues +URL: https://github.com/eveyp/RStata +BugReports: https://github.com/eveyp/RStata/issues Imports: foreign, haven, From 74b2fe393ecde0ad2cf1c405816009b7adb86645 Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Fri, 27 Jan 2023 13:45:09 -0800 Subject: [PATCH 14/38] bump version number --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index ca9439b..e275e5b 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: RStata Title: A Bit of Glue Between R and Stata -Version: 1.2.0 +Version: 1.3.0 Authors@R: c( person("Eve", "Perry", email = "eve@eveperry.com", role = c("aut", "cre")), person("Luca", "Braglia", email = "lbraglia@gmail.com", role = "aut")) From 84052a242b149a1f179b1287a72db2ea2318dcff Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Fri, 27 Jan 2023 14:34:00 -0800 Subject: [PATCH 15/38] fix saveold bug --- DESCRIPTION | 2 +- R/stata.R | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index e275e5b..e3f2c6d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: RStata Title: A Bit of Glue Between R and Stata -Version: 1.3.0 +Version: 1.3.1 Authors@R: c( person("Eve", "Perry", email = "eve@eveperry.com", role = c("aut", "cre")), person("Luca", "Braglia", email = "lbraglia@gmail.com", role = "aut")) diff --git a/R/stata.R b/R/stata.R index 7567d4d..7e1d611 100644 --- a/R/stata.R +++ b/R/stata.R @@ -188,11 +188,12 @@ stata <- function(src = stop("At least 'src' must be specified"), ## for Stata 14, saveold defaults to a Stata 13 dta file ## -> use the (Stata 14 only) saveold option: "version(12)" to allow ## foreign::read.dta() read compatibility - if (dataOut){ - save_cmd <- sprintf("%s %s%s", - if (stataVersion >= 13) "saveold" else "save", - tools::file_path_sans_ext(dtaOutFile), - if (stataVersion >= 14) ", version(12)" else "") + if (dataOut) { + save_cmd <- sprintf( + "%s %s%s", + if (stataVersion >= 13 & saveold) "saveold" else "save", + tools::file_path_sans_ext(dtaOutFile), + if (stataVersion >= 14 & saveold) ", version(12)" else "") SRC <- c(SRC, save_cmd) } From 17b7ea9c5a0f467c11786f2ec55dc54366e5d9e9 Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Fri, 27 Jan 2023 14:50:59 -0800 Subject: [PATCH 16/38] force version 13 for readstata13 --- R/stata.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/stata.R b/R/stata.R index 7e1d611..7f85a0a 100644 --- a/R/stata.R +++ b/R/stata.R @@ -145,7 +145,7 @@ stata <- function(src = stop("At least 'src' must be specified"), if (package == "readstata13") { readstata13::save.dta13( - data.in, file = dtaInFile, version = package_stata_version, ... + data.in, file = dtaInFile, version = 13, ... ) } } From 274deee14def5555b1e97ea03394d9eb33c113d2 Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Mon, 6 Feb 2023 12:41:48 -0800 Subject: [PATCH 17/38] coerce to data.frame for readstata13 bump version number use tempfiles for callr support --- DESCRIPTION | 2 +- R/stata.R | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index e3f2c6d..be01904 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: RStata Title: A Bit of Glue Between R and Stata -Version: 1.3.1 +Version: 1.3.2 Authors@R: c( person("Eve", "Perry", email = "eve@eveperry.com", role = c("aut", "cre")), person("Luca", "Braglia", email = "lbraglia@gmail.com", role = "aut")) diff --git a/R/stata.R b/R/stata.R index 7f85a0a..9ee4297 100644 --- a/R/stata.R +++ b/R/stata.R @@ -127,8 +127,7 @@ stata <- function(src = stop("At least 'src' must be specified"), if (dataIn){ ## dtaInFile <- tempfile("RStataDataIn", fileext = ".dta") ## Windows/Stata8 unhappy? - dtaInFile <- "RStataDataIn.dta" - on.exit(unlink(dtaInFile), add = TRUE) + dtaInFile <- tempfile("RStataDataIn", fileext = ".dta") if (stataVersion <= 7) { foreign::write.dta(data.in, file = dtaInFile, @@ -145,7 +144,7 @@ stata <- function(src = stop("At least 'src' must be specified"), if (package == "readstata13") { readstata13::save.dta13( - data.in, file = dtaInFile, version = 13, ... + as.data.frame(data.in), file = dtaInFile, version = 13, ... ) } } @@ -154,7 +153,7 @@ stata <- function(src = stop("At least 'src' must be specified"), if (dataOut) { ## dtaOutFile <- tempfile("RStataDataOut", fileext = ".dta") ## Windows/Stata8 unhappy? - dtaOutFile <- "RStataDataOut.dta" + dtaOutFile <- tempfile("RStataDataOut", fileext = ".dta") on.exit(unlink(dtaOutFile), add = TRUE) } From 5dd855fe4d3d095b6ac880c7ac78256cfb83335d Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Mon, 13 Feb 2023 13:42:47 -0800 Subject: [PATCH 18/38] formatting, processx, & tempfiles --- R/stata.R | 377 +++++++++++++++++++++++++++++------------------------- 1 file changed, 200 insertions(+), 177 deletions(-) diff --git a/R/stata.R b/R/stata.R index 9ee4297..020d009 100644 --- a/R/stata.R +++ b/R/stata.R @@ -63,191 +63,214 @@ #' (y <- stata("replace a = 2", data.in = x, data.out = TRUE)) #' } #' @export -stata <- function(src = stop("At least 'src' must be specified"), - data.in = NULL, - data.out = FALSE, - - saveold = FALSE, - package = "haven", - stata.path = getOption("RStata.StataPath", stop("You need to set up a Stata path; ?chooseStataBin")), - stata.version = getOption("RStata.StataVersion", stop("You need to specify your Stata version")), - stata.echo = getOption("RStata.StataEcho", TRUE), - ... - ) -{ - ## ------------------------- - ## Data validation and setup - ## ------------------------- - if (!is.character(src)) - stop("src must be a character") - - if (!(is.null(data.in) | is.data.frame(data.in))) - stop("data.in must be NULL or a data.frame") - - if (!is.logical(data.out)) - stop("data.out must be logical") - - if (!is.numeric(stata.version)) - stop("stata.version must be numeric") - - if (!is.logical(stata.echo)) - stop("stata.echo must be logical") - - if (!package %in% c("haven", "readstata13")) - stop("package must be either 'haven' or 'readstata13'") - - OS <- Sys.info()["sysname"] - OS.type <- .Platform$OS.type - SRC <- unlist(lapply(src, strsplit, '\n')) - dataIn <- is.data.frame(data.in) - dataOut <- data.out[1L] - stataVersion <- stata.version[1L] - stataEcho <- stata.echo[1L] - - ## ----------------- - ## OS related config - ## ----------------- - ## in Windows and batch mode a RStata.log (naming after RStata.do - ## below) is generated in the current directory - - if (OS %in% "Windows") { - winRStataLog <- "RStata.log" - on.exit(unlink(winRStataLog)) - } +stata <- function( + src = stop("At least 'src' must be specified"), + data.in = NULL, + data.out = FALSE, + saveold = FALSE, + package = "haven", + stata.path = getOption("RStata.StataPath", stop("You need to set up a Stata path; ?chooseStataBin")), + stata.version = getOption("RStata.StataVersion", stop("You need to specify your Stata version")), + stata.echo = getOption("RStata.StataEcho", TRUE), + ... +) { + ## ------------------------- + ## Data validation and setup + ## ------------------------- + if (!is.character(src)) + stop("src must be a character") - ## ----- - ## Files - ## ----- - - ## tempfile could be misleading if the do source other dos - ## with relative paths - doFile <- "RStata.do" - on.exit(unlink(doFile), add = TRUE) - - if (dataIn){ - ## dtaInFile <- tempfile("RStataDataIn", fileext = ".dta") - ## Windows/Stata8 unhappy? - dtaInFile <- tempfile("RStataDataIn", fileext = ".dta") - if (stataVersion <= 7) { - foreign::write.dta(data.in, - file = dtaInFile, - version = 6L, - ...) - } else { - package_stata_version = if (stataVersion > 15) 15L else stataVersion - - if (package == "haven") { - haven::write_dta( - data.in, path = dtaInFile, version = package_stata_version, ... - ) - } - - if (package == "readstata13") { - readstata13::save.dta13( - as.data.frame(data.in), file = dtaInFile, version = 13, ... - ) - } - } - } - - if (dataOut) { - ## dtaOutFile <- tempfile("RStataDataOut", fileext = ".dta") - ## Windows/Stata8 unhappy? - dtaOutFile <- tempfile("RStataDataOut", fileext = ".dta") - on.exit(unlink(dtaOutFile), add = TRUE) + if (!(is.null(data.in) | is.data.frame(data.in))) + stop("data.in must be NULL or a data.frame") + + if (!is.logical(data.out)) + stop("data.out must be logical") + + if (!is.numeric(stata.version)) + stop("stata.version must be numeric") + + if (!is.logical(stata.echo)) + stop("stata.echo must be logical") + + if (!package %in% c("haven", "readstata13")) + stop("package must be either 'haven' or 'readstata13'") + + OS <- Sys.info()["sysname"] + OS.type <- .Platform$OS.type + SRC <- unlist(lapply(src, strsplit, '\n')) + dataIn <- is.data.frame(data.in) + dataOut <- data.out[1L] + stataVersion <- stata.version[1L] + stataEcho <- stata.echo[1L] + + ## ----------------- + ## OS related config + ## ----------------- + ## in Windows and batch mode a RStata.log (naming after RStata.do + ## below) is generated in the current directory + + if (OS %in% "Windows") { + winRStataLog <- "RStata.log" + on.exit(unlink(winRStataLog)) + } + + ## ----- + ## Files + ## ----- + + ## tempfile could be misleading if the do source other dos + ## with relative paths + doFile <- "RStata.do" + on.exit(unlink(doFile), add = TRUE) + + if (dataIn){ + ## dtaInFile <- tempfile("RStataDataIn", fileext = ".dta") + ## Windows/Stata8 unhappy? + dtaInFile <- fs::file_temp("RStataDataIn", ext = ".dta") + if (stataVersion <= 7) { + foreign::write.dta( + data.in, + file = dtaInFile, + version = 6L, + ... + ) + } else { + package_stata_version = if (stataVersion > 15) 15L else stataVersion + + if (package == "haven") { + haven::write_dta( + data.in, path = dtaInFile, version = package_stata_version, ... + ) + } + + if (package == "readstata13") { + readstata13::save.dta13( + as.data.frame(data.in), file = dtaInFile, version = 13, ... + ) + } } - - ## ------------------------- - ## Creating the .do file ... - ## ------------------------- + } + + if (dataOut) { + ## dtaOutFile <- tempfile("RStataDataOut", fileext = ".dta") + ## Windows/Stata8 unhappy? + dtaOutFile <- fs::file_temp("RStataDataOut", ext = ".dta") + # on.exit(unlink(dtaOutFile), add = TRUE) + } + + ## ------------------------- + ## Creating the .do file ... + ## ------------------------- + + ## External .do script 'support': KIS + if (file.exists(SRC[1L])) + SRC <- readLines(SRC[1L]) + + ## put a placeholder around the part of interest, in order to find + ## it easily (when removing overhead/setup code for each run) + cut_me_here <- 'RSTATA: cut me here' + cut_me_comment <- paste0('/*', cut_me_here, '*/') + + ## capture noisily and set cut points + SRC <- c( + ifelse( + dataIn, + sprintf("use %s", tools::file_path_sans_ext(dtaInFile)), + '' - ## External .do script 'support': KIS - if (file.exists(SRC[1L])) - SRC <- readLines(SRC[1L]) - - ## put a placeholder around the part of interest, in order to find - ## it easily (when removing overhead/setup code for each run) - cut_me_here <- 'RSTATA: cut me here' - cut_me_comment <- paste0('/*', cut_me_here, '*/') - - ## capture noisily and set cut points - SRC <- c( - {if (dataIn) sprintf("use %s", tools::file_path_sans_ext(dtaInFile)) - else ''}, + ), 'capture noisily {', cut_me_comment, SRC, cut_me_comment, - '} /* end capture noisily */') - - ## set more off just to be sure nothing will freeze (hopefully :) ) - SRC <- c('set more off', SRC) - - ## put a save or saveold at the end of .do if data.out == TRUE - ## for Stata 14, saveold defaults to a Stata 13 dta file - ## -> use the (Stata 14 only) saveold option: "version(12)" to allow - ## foreign::read.dta() read compatibility - if (dataOut) { - save_cmd <- sprintf( - "%s %s%s", - if (stataVersion >= 13 & saveold) "saveold" else "save", - tools::file_path_sans_ext(dtaOutFile), - if (stataVersion >= 14 & saveold) ", version(12)" else "") - SRC <- c(SRC, save_cmd) + '} /* end capture noisily */' + ) + + ## set more off just to be sure nothing will freeze (hopefully :) ) + SRC <- c('set more off', SRC) + + ## put a save or saveold at the end of .do if data.out == TRUE + ## for Stata 14, saveold defaults to a Stata 13 dta file + ## -> use the (Stata 14 only) saveold option: "version(12)" to allow + ## foreign::read.dta() read compatibility + if (dataOut) { + # save_cmd <- sprintf( + # "%s %s%s", + # ifelse(stataVersion >= 13 & saveold, "saveold", "save"), + # tools::file_path_sans_ext(dtaOutFile), + # ifelse(stataVersion >= 14 & saveold, ", version(12)", "") + save_version = ifelse(stataVersion >= 13 & saveold, "saveold", "save") + save_options = ifelse(stataVersion >= 14 & saveold, ", version(12)", "") + save_cmd = glue::glue('{save_version} "{dtaOutFile}"{save_options}') + SRC <- c(SRC, save_cmd) + } + + ## adding this command to the end simplify life if user make changes but + ## doesn't want a data.frame back + SRC <- c(SRC, "exit, clear STATA") + + ## ------------- + ## Stata command + ## ------------- + + ## With Windows version, /e is almost always needed (if Stata is + ## installed with GUI) + stataCmd <- paste( + stata.path, + ifelse(OS %in% "Windows", "/e", ""), + "do", + doFile + ) + + ## --- + ## IPC + ## --- + ## setup the .do file + ## con <- fifo(doFile, "w+") # <- freeze with fifo in Window + con <- file(doFile, "w") + writeLines(SRC, con) + close(con) + + ## execute Stata + # rdl <- pipe(stataCmd, "r") + processx::run( + "C:/Program Files/Stata17/StataMP-64.exe", + args = c( + "/e", + doFile + ), + echo_cmd = TRUE, + echo = TRUE, + stdout = "stdout.txt", + stderr_to_stdout = TRUE + ) + stataLog <- readLines("stdout.txt") + # close(rdl) + + if (stataEcho) { + if (OS %in% "Windows") + stataLog <- readLines(winRStataLog) + ## postprocess log, keeping only the output of interest (between rows + ## having /* RSTATA: cut me here */ + cutpoints <- grep(cut_me_here, stataLog) + stataLog <- stataLog[seq.int(cutpoints[1] + 1, cutpoints[2] - 1)] + cat(stataLog, sep = "\n") + } + + ## ------------------ + ## Get data outputted + ## ------------------ + if (dataOut) { + if (stataVersion <= 7) { + res <- foreign::read.dta(dtaOutFile, ...) } - - ## adding this command to the end simplify life if user make changes but - ## doesn't want a data.frame back - SRC <- c(SRC, "exit, clear STATA") - - ## ------------- - ## Stata command - ## ------------- - - ## With Windows version, /e is almost always needed (if Stata is - ## installed with GUI) - stataCmd <- paste(stata.path, - if (OS %in% "Windows") "/e" else "", - "do", - doFile) - - ## --- - ## IPC - ## --- - ## setup the .do file - ## con <- fifo(doFile, "w+") # <- freeze with fifo in Window - con <- file(doFile, "w") - writeLines(SRC, con) - close(con) - - ## execute Stata - rdl <- pipe(stataCmd, "r") - stataLog <- readLines(rdl) - close(rdl) - - if (stataEcho) { - if (OS %in% "Windows") stataLog <- readLines(winRStataLog) - ## postprocess log, keeping only the output of interest (between rows - ## having /* RSTATA: cut me here */ - cutpoints <- grep(cut_me_here, stataLog) - stataLog <- stataLog[seq.int(cutpoints[1] + 1, cutpoints[2] - 1)] - cat(stataLog, sep = "\n") + else if (package == "haven") { + res <- haven::read_dta(dtaOutFile, ...) } - - ## ------------------ - ## Get data outputted - ## ------------------ - if (dataOut) { - if (stataVersion <= 7) { - res <- foreign::read.dta(dtaOutFile, ...) - } - else if (package == "haven") { - res <- haven::read_dta(dtaOutFile, ...) - } - else if (package == "readstata13") { - res <- readstata13::read.dta13(dtaOutFile, ...) - } - - invisible(res) + else if (package == "readstata13") { + res <- readstata13::read.dta13(dtaOutFile, ...) } + + invisible(res) + } } From 49b91ddfcb674b8cc001eb4580f5e29f3d727040 Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Mon, 13 Feb 2023 13:43:17 -0800 Subject: [PATCH 19/38] update dependencies --- DESCRIPTION | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index be01904..2f77e35 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -14,7 +14,9 @@ Imports: haven, readstata13, tools, - utils + utils, + processx, + fs License: GPL-3 RoxygenNote: 7.2.0 Encoding: UTF-8 From b85dda0c34be5951832758a64930d7db78bc40c6 Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Mon, 13 Feb 2023 13:43:24 -0800 Subject: [PATCH 20/38] bump version --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 2f77e35..d5b76d9 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: RStata Title: A Bit of Glue Between R and Stata -Version: 1.3.2 +Version: 1.3.2.9001 Authors@R: c( person("Eve", "Perry", email = "eve@eveperry.com", role = c("aut", "cre")), person("Luca", "Braglia", email = "lbraglia@gmail.com", role = "aut")) From 912b06603512b48d4362238c790816545d8b6f1d Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Mon, 13 Feb 2023 15:11:51 -0800 Subject: [PATCH 21/38] fix old comments --- R/stata.R | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/R/stata.R b/R/stata.R index 020d009..2f8764b 100644 --- a/R/stata.R +++ b/R/stata.R @@ -124,8 +124,6 @@ stata <- function( on.exit(unlink(doFile), add = TRUE) if (dataIn){ - ## dtaInFile <- tempfile("RStataDataIn", fileext = ".dta") - ## Windows/Stata8 unhappy? dtaInFile <- fs::file_temp("RStataDataIn", ext = ".dta") if (stataVersion <= 7) { foreign::write.dta( @@ -152,10 +150,7 @@ stata <- function( } if (dataOut) { - ## dtaOutFile <- tempfile("RStataDataOut", fileext = ".dta") - ## Windows/Stata8 unhappy? dtaOutFile <- fs::file_temp("RStataDataOut", ext = ".dta") - # on.exit(unlink(dtaOutFile), add = TRUE) } ## ------------------------- @@ -188,20 +183,17 @@ stata <- function( ## set more off just to be sure nothing will freeze (hopefully :) ) SRC <- c('set more off', SRC) - - ## put a save or saveold at the end of .do if data.out == TRUE - ## for Stata 14, saveold defaults to a Stata 13 dta file - ## -> use the (Stata 14 only) saveold option: "version(12)" to allow - ## foreign::read.dta() read compatibility + if (dataOut) { - # save_cmd <- sprintf( - # "%s %s%s", - # ifelse(stataVersion >= 13 & saveold, "saveold", "save"), - # tools::file_path_sans_ext(dtaOutFile), - # ifelse(stataVersion >= 14 & saveold, ", version(12)", "") + ## put a save or saveold at the end of .do if data.out == TRUE save_version = ifelse(stataVersion >= 13 & saveold, "saveold", "save") + ## for Stata 14, saveold defaults to a Stata 13 dta file + ## -> use the (Stata 14 only) saveold option: "version(12)" to allow + ## foreign::read.dta() read compatibility save_options = ifelse(stataVersion >= 14 & saveold, ", version(12)", "") + save_cmd = glue::glue('{save_version} "{dtaOutFile}"{save_options}') + SRC <- c(SRC, save_cmd) } @@ -232,7 +224,6 @@ stata <- function( close(con) ## execute Stata - # rdl <- pipe(stataCmd, "r") processx::run( "C:/Program Files/Stata17/StataMP-64.exe", args = c( @@ -245,8 +236,7 @@ stata <- function( stderr_to_stdout = TRUE ) stataLog <- readLines("stdout.txt") - # close(rdl) - + if (stataEcho) { if (OS %in% "Windows") stataLog <- readLines(winRStataLog) From 84ff8c43898b180b9ba743748dc7e01f4f775149 Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Mon, 13 Feb 2023 15:12:23 -0800 Subject: [PATCH 22/38] clean up processx call --- R/stata.R | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/R/stata.R b/R/stata.R index 2f8764b..1fb8450 100644 --- a/R/stata.R +++ b/R/stata.R @@ -205,15 +205,6 @@ stata <- function( ## Stata command ## ------------- - ## With Windows version, /e is almost always needed (if Stata is - ## installed with GUI) - stataCmd <- paste( - stata.path, - ifelse(OS %in% "Windows", "/e", ""), - "do", - doFile - ) - ## --- ## IPC ## --- @@ -223,15 +214,19 @@ stata <- function( writeLines(SRC, con) close(con) + stata_args = doFile + + ## With Windows version, /e is almost always needed (if Stata is + ## installed with GUI) + if (OS %in% "Windows") + stata_args = c("/e", stata_args) + ## execute Stata processx::run( - "C:/Program Files/Stata17/StataMP-64.exe", - args = c( - "/e", - doFile - ), - echo_cmd = TRUE, - echo = TRUE, + stata.path, + args = stata_args, + echo_cmd = stata.echo, + echo = stata.echo, stdout = "stdout.txt", stderr_to_stdout = TRUE ) From b3a1c4b4e666bf0347068c29e7a2522cba6afb9e Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Mon, 13 Feb 2023 15:12:38 -0800 Subject: [PATCH 23/38] clean up stata use call --- R/stata.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/stata.R b/R/stata.R index 1fb8450..c42824b 100644 --- a/R/stata.R +++ b/R/stata.R @@ -170,9 +170,9 @@ stata <- function( SRC <- c( ifelse( dataIn, - sprintf("use %s", tools::file_path_sans_ext(dtaInFile)), + # sprintf("use %s", tools::file_path_sans_ext(dtaInFile)), + glue::glue("use {dtaInFile}"), '' - ), 'capture noisily {', cut_me_comment, From b23c53bad2083891829ddf48d6dd6f65652f6422 Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Mon, 13 Feb 2023 15:12:47 -0800 Subject: [PATCH 24/38] add glue dependency --- DESCRIPTION | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index d5b76d9..c9c89e9 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -16,7 +16,8 @@ Imports: tools, utils, processx, - fs + fs, + glue License: GPL-3 RoxygenNote: 7.2.0 Encoding: UTF-8 From 93bc491ac604bb641b1662b986df23ac1c55dbb8 Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Mon, 13 Feb 2023 15:12:53 -0800 Subject: [PATCH 25/38] bump version --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index c9c89e9..5c95530 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: RStata Title: A Bit of Glue Between R and Stata -Version: 1.3.2.9001 +Version: 1.3.2.9002 Authors@R: c( person("Eve", "Perry", email = "eve@eveperry.com", role = c("aut", "cre")), person("Luca", "Braglia", email = "lbraglia@gmail.com", role = "aut")) From 87d8c5f790b0de08b6692ced32171031b13cb3dd Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Mon, 13 Feb 2023 17:46:19 -0800 Subject: [PATCH 26/38] allow stata path & version in env variables --- R/stata.R | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/R/stata.R b/R/stata.R index c42824b..f613fad 100644 --- a/R/stata.R +++ b/R/stata.R @@ -69,8 +69,8 @@ stata <- function( data.out = FALSE, saveold = FALSE, package = "haven", - stata.path = getOption("RStata.StataPath", stop("You need to set up a Stata path; ?chooseStataBin")), - stata.version = getOption("RStata.StataVersion", stop("You need to specify your Stata version")), + stata.path = getOption("RStata.StataPath", Sys.getenv("STATA_PATH")), + stata.version = getOption("RStata.StataVersion", Sys.getenv("STATA_VERSION")), stata.echo = getOption("RStata.StataEcho", TRUE), ... ) { @@ -86,6 +86,9 @@ stata <- function( if (!is.logical(data.out)) stop("data.out must be logical") + if (is.null(stata.version) | stata.version == "") + stop("You need to specify your Stata version") + if (!is.numeric(stata.version)) stop("stata.version must be numeric") @@ -95,6 +98,9 @@ stata <- function( if (!package %in% c("haven", "readstata13")) stop("package must be either 'haven' or 'readstata13'") + if (is.null(stata.path) | stata.path == "") + stop("You need to set up a Stata path; ?chooseStataBin") + OS <- Sys.info()["sysname"] OS.type <- .Platform$OS.type SRC <- unlist(lapply(src, strsplit, '\n')) From 7356126c0d95fa87c341bf67cc7e54895354d24a Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Mon, 13 Feb 2023 17:46:29 -0800 Subject: [PATCH 27/38] bump version --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 5c95530..09a88ed 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: RStata Title: A Bit of Glue Between R and Stata -Version: 1.3.2.9002 +Version: 1.3.2.9003 Authors@R: c( person("Eve", "Perry", email = "eve@eveperry.com", role = c("aut", "cre")), person("Luca", "Braglia", email = "lbraglia@gmail.com", role = "aut")) From 6f43e821df954c8fa89b9b5630f8866837ec48de Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Tue, 21 Feb 2023 16:13:39 -0800 Subject: [PATCH 28/38] simplify path and version arguments --- R/stata.R | 49 +++++++++++++++++++++++++++++++++++-------------- man/stata.Rd | 16 ++++++++++------ 2 files changed, 45 insertions(+), 20 deletions(-) diff --git a/R/stata.R b/R/stata.R index f613fad..55b1c66 100644 --- a/R/stata.R +++ b/R/stata.R @@ -1,19 +1,20 @@ #' Send commands to a Stata process #' #' Function that sends commands to a Stata process. -#' @param src character vector of length 1 (path to \code{.do} file) or more -#' (a set of stata commands). See examples. +#' @param src character vector of length 1 (path to \code{.do} file) or more (a +#' set of stata commands). See examples. #' @param data.in \code{\link{data.frame}} to be passed to Stata -#' @param data.out logical value. If \code{TRUE}, the data at the end of -#' the Stata command are returned to R. +#' @param data.out logical value. If \code{TRUE}, the data at the end of the +#' Stata command are returned to R. #' @param stata.path Stata command to be used #' @param stata.version Version of Stata used -#' @param stata.echo logical value. If \code{TRUE} stata text output will be printed +#' @param stata.echo logical value. If \code{TRUE} stata text output will be +#' printed #' @param ... parameter passed to \code{\link{write.dta}} #' -#' It uses \code{\link[haven]{haven}} (default) or -#' \code{\link[readstata13]{readstata13}} for Stata version 8 and beyond, and -#' uses \code{foreign} for Stata version 7 and prior. +#' It uses \code{\link[haven]{haven}} (default) or +#' \code{\link[readstata13]{readstata13}} for Stata version 8 and beyond, and +#' uses \code{foreign} for Stata version 7 and prior. #' #' @param src character vector of length 1 (path to \code{.do} file) or more (a #' set of stata commands). See examples. @@ -25,8 +26,14 @@ #' @param package character string. R package to use to read/write Stata #' datasets for Stata versions 8 and beyond. can either be \code{"haven"} or #' \code{"readstata13"}. defaults to \code{"haven"}. -#' @param stata.path Stata command to be used -#' @param stata.version Version of Stata used +#' @param stata.path Stata command to be used. Can be supplied in the +#' environment variable \code{STATA_PATH} or the R option +#' \code{RStata.StataPath}. The environmental variable is preferred over the R +#' option. +#' @param stata.version Version of Stata used. Can be supplied in the +#' environment variable \code{STATA_VERSION} or the R option +#' \code{RStata.StataVersion}. The environmental variable is preferred over +#' the R option. #' @param stata.echo logical value. If \code{TRUE} stata text output will be #' printed #' @param ... parameter passed to \code{\link{write_dta}} or @@ -69,8 +76,8 @@ stata <- function( data.out = FALSE, saveold = FALSE, package = "haven", - stata.path = getOption("RStata.StataPath", Sys.getenv("STATA_PATH")), - stata.version = getOption("RStata.StataVersion", Sys.getenv("STATA_VERSION")), + stata.path = NULL, + stata.version = NULL, stata.echo = getOption("RStata.StataEcho", TRUE), ... ) { @@ -86,8 +93,15 @@ stata <- function( if (!is.logical(data.out)) stop("data.out must be logical") - if (is.null(stata.version) | stata.version == "") + if (is.null(stata.version) & !is.null(getOption("RStata.StataVersion"))) { + stata.version = getOption("RStata.StataVersion") + } + else if (is.null(stata.version) & !grepl("\\D", Sys.getenv("STATA_VERSION"))) { + stata.version = as.integer(Sys.getenv("STATA_VERSION")) + } + else { stop("You need to specify your Stata version") + } if (!is.numeric(stata.version)) stop("stata.version must be numeric") @@ -98,8 +112,15 @@ stata <- function( if (!package %in% c("haven", "readstata13")) stop("package must be either 'haven' or 'readstata13'") - if (is.null(stata.path) | stata.path == "") + if (is.null(stata.path) & !is.null(getOption("RStata.StataPath"))) { + stata.path = getOption("RStata.StataPath") + } + else if (is.null(stata.path) & Sys.getenv("STATA_PATH") != "") { + stata.path = Sys.getenv("STATA_PATH") + } + else { stop("You need to set up a Stata path; ?chooseStataBin") + } OS <- Sys.info()["sysname"] OS.type <- .Platform$OS.type diff --git a/man/stata.Rd b/man/stata.Rd index c04db2f..2135c80 100644 --- a/man/stata.Rd +++ b/man/stata.Rd @@ -10,10 +10,8 @@ stata( data.out = FALSE, saveold = FALSE, package = "haven", - stata.path = getOption("RStata.StataPath", - stop("You need to set up a Stata path; ?chooseStataBin")), - stata.version = getOption("RStata.StataVersion", - stop("You need to specify your Stata version")), + stata.path = NULL, + stata.version = NULL, stata.echo = getOption("RStata.StataEcho", TRUE), ... ) @@ -34,9 +32,15 @@ Stata command are returned to R.} datasets for Stata versions 8 and beyond. can either be \code{"haven"} or \code{"readstata13"}. defaults to \code{"haven"}.} -\item{stata.path}{Stata command to be used} +\item{stata.path}{Stata command to be used. Can be supplied in the +environment variable \code{STATA_PATH} or the R option +\code{RStata.StataPath}. The environmental variable is preferred over the R +option.} -\item{stata.version}{Version of Stata used} +\item{stata.version}{Version of Stata used. Can be supplied in the +environment variable \code{STATA_VERSION} or the R option +\code{RStata.StataVersion}. The environmental variable is preferred over +the R option.} \item{stata.echo}{logical value. If \code{TRUE} stata text output will be printed} From a7c46f78676c9500fedfe96d393f35b67a49015b Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Tue, 21 Feb 2023 16:14:04 -0800 Subject: [PATCH 29/38] remove saved stdout.txt on exit --- R/stata.R | 2 ++ 1 file changed, 2 insertions(+) diff --git a/R/stata.R b/R/stata.R index 55b1c66..0e9b141 100644 --- a/R/stata.R +++ b/R/stata.R @@ -248,6 +248,8 @@ stata <- function( if (OS %in% "Windows") stata_args = c("/e", stata_args) + on.exit(unlink("stdout.txt"), add = TRUE) + ## execute Stata processx::run( stata.path, From f8f9ff004f2d6e18562b74e8042c24d638b0311b Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Tue, 21 Feb 2023 16:14:15 -0800 Subject: [PATCH 30/38] get rid of commented out code --- R/stata.R | 1 - 1 file changed, 1 deletion(-) diff --git a/R/stata.R b/R/stata.R index 0e9b141..e6cdc1f 100644 --- a/R/stata.R +++ b/R/stata.R @@ -197,7 +197,6 @@ stata <- function( SRC <- c( ifelse( dataIn, - # sprintf("use %s", tools::file_path_sans_ext(dtaInFile)), glue::glue("use {dtaInFile}"), '' ), From 1c98776444aeaf45b5ac690483a23fe59c814421 Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Tue, 21 Feb 2023 16:14:36 -0800 Subject: [PATCH 31/38] add tests --- DESCRIPTION | 3 + tests/testthat.R | 4 + tests/testthat/_snaps/stata.md | 401 ++++++++++++++++++++++++++++++++ tests/testthat/fixtures/test.do | 2 + tests/testthat/test-stata.R | 27 +++ 5 files changed, 437 insertions(+) create mode 100644 tests/testthat.R create mode 100644 tests/testthat/_snaps/stata.md create mode 100644 tests/testthat/fixtures/test.do create mode 100644 tests/testthat/test-stata.R diff --git a/DESCRIPTION b/DESCRIPTION index 09a88ed..52c7ee5 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -21,3 +21,6 @@ Imports: License: GPL-3 RoxygenNote: 7.2.0 Encoding: UTF-8 +Suggests: + testthat (>= 3.0.0) +Config/testthat/edition: 3 diff --git a/tests/testthat.R b/tests/testthat.R new file mode 100644 index 0000000..67a7ded --- /dev/null +++ b/tests/testthat.R @@ -0,0 +1,4 @@ +library(testthat) +library(RStata) + +test_check("RStata") diff --git a/tests/testthat/_snaps/stata.md b/tests/testthat/_snaps/stata.md new file mode 100644 index 0000000..0fedddd --- /dev/null +++ b/tests/testthat/_snaps/stata.md @@ -0,0 +1,401 @@ +# string cmd input works + + Code + stata("sum", mtcars) + Output + Running "C:\\Program Files\\Stata17\\StataMP-64.exe" /e RStata.do + . sum + + Variable | Obs Mean Std. dev. Min Max + -------------+--------------------------------------------------------- + mpg | 32 20.09062 6.026948 10.4 33.9 + cyl | 32 6.1875 1.785922 4 8 + disp | 32 230.7219 123.9387 71.1 472 + hp | 32 146.6875 68.56287 52 335 + drat | 32 3.596563 .5346787 2.76 4.93 + -------------+--------------------------------------------------------- + wt | 32 3.21725 .9784574 1.513 5.424 + qsec | 32 17.84875 1.786943 14.5 22.9 + vs | 32 .4375 .5040161 0 1 + am | 32 .40625 .4989909 0 1 + gear | 32 3.6875 .7378041 3 5 + -------------+--------------------------------------------------------- + carb | 32 2.8125 1.6152 1 8 + +# string cmd input works with data.out + + Code + stata("sum", mtcars, data.out = TRUE) + Output + Running "C:\\Program Files\\Stata17\\StataMP-64.exe" /e RStata.do + . sum + + Variable | Obs Mean Std. dev. Min Max + -------------+--------------------------------------------------------- + mpg | 32 20.09062 6.026948 10.4 33.9 + cyl | 32 6.1875 1.785922 4 8 + disp | 32 230.7219 123.9387 71.1 472 + hp | 32 146.6875 68.56287 52 335 + drat | 32 3.596563 .5346787 2.76 4.93 + -------------+--------------------------------------------------------- + wt | 32 3.21725 .9784574 1.513 5.424 + qsec | 32 17.84875 1.786943 14.5 22.9 + vs | 32 .4375 .5040161 0 1 + am | 32 .40625 .4989909 0 1 + gear | 32 3.6875 .7378041 3 5 + -------------+--------------------------------------------------------- + carb | 32 2.8125 1.6152 1 8 + +--- + + { + "type": "list", + "attributes": { + "class": { + "type": "character", + "attributes": {}, + "value": ["tbl_df", "tbl", "data.frame"] + }, + "row.names": { + "type": "integer", + "attributes": {}, + "value": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32] + }, + "names": { + "type": "character", + "attributes": {}, + "value": ["mpg", "cyl", "disp", "hp", "drat", "wt", "qsec", "vs", "am", "gear", "carb"] + } + }, + "value": [ + { + "type": "double", + "attributes": { + "format.stata": { + "type": "character", + "attributes": {}, + "value": ["%10.0g"] + } + }, + "value": [21, 21, 22.8, 21.4, 18.7, 18.1, 14.3, 24.4, 22.8, 19.2, 17.8, 16.4, 17.3, 15.2, 10.4, 10.4, 14.7, 32.4, 30.4, 33.9, 21.5, 15.5, 15.2, 13.3, 19.2, 27.3, 26, 30.4, 15.8, 19.7, 15, 21.4] + }, + { + "type": "double", + "attributes": { + "format.stata": { + "type": "character", + "attributes": {}, + "value": ["%10.0g"] + } + }, + "value": [6, 6, 4, 6, 8, 6, 8, 4, 4, 6, 6, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 8, 8, 8, 8, 4, 4, 4, 8, 6, 8, 4] + }, + { + "type": "double", + "attributes": { + "format.stata": { + "type": "character", + "attributes": {}, + "value": ["%10.0g"] + } + }, + "value": [160, 160, 108, 258, 360, 225, 360, 146.7, 140.8, 167.6, 167.6, 275.8, 275.8, 275.8, 472, 460, 440, 78.7, 75.7, 71.1, 120.1, 318, 304, 350, 400, 79, 120.3, 95.1, 351, 145, 301, 121] + }, + { + "type": "double", + "attributes": { + "format.stata": { + "type": "character", + "attributes": {}, + "value": ["%10.0g"] + } + }, + "value": [110, 110, 93, 110, 175, 105, 245, 62, 95, 123, 123, 180, 180, 180, 205, 215, 230, 66, 52, 65, 97, 150, 150, 245, 175, 66, 91, 113, 264, 175, 335, 109] + }, + { + "type": "double", + "attributes": { + "format.stata": { + "type": "character", + "attributes": {}, + "value": ["%10.0g"] + } + }, + "value": [3.9, 3.9, 3.85, 3.08, 3.15, 2.76, 3.21, 3.69, 3.92, 3.92, 3.92, 3.07, 3.07, 3.07, 2.93, 3, 3.23, 4.08, 4.93, 4.22, 3.7, 2.76, 3.15, 3.73, 3.08, 4.08, 4.43, 3.77, 4.22, 3.62, 3.54, 4.11] + }, + { + "type": "double", + "attributes": { + "format.stata": { + "type": "character", + "attributes": {}, + "value": ["%10.0g"] + } + }, + "value": [2.62, 2.875, 2.32, 3.215, 3.44, 3.46, 3.57, 3.19, 3.15, 3.44, 3.44, 4.07, 3.73, 3.78, 5.25, 5.424, 5.345, 2.2, 1.615, 1.835, 2.465, 3.52, 3.435, 3.84, 3.845, 1.935, 2.14, 1.513, 3.17, 2.77, 3.57, 2.78] + }, + { + "type": "double", + "attributes": { + "format.stata": { + "type": "character", + "attributes": {}, + "value": ["%10.0g"] + } + }, + "value": [16.46, 17.02, 18.61, 19.44, 17.02, 20.22, 15.84, 20, 22.9, 18.3, 18.9, 17.4, 17.6, 18, 17.98, 17.82, 17.42, 19.47, 18.52, 19.9, 20.01, 16.87, 17.3, 15.41, 17.05, 18.9, 16.7, 16.9, 14.5, 15.5, 14.6, 18.6] + }, + { + "type": "double", + "attributes": { + "format.stata": { + "type": "character", + "attributes": {}, + "value": ["%10.0g"] + } + }, + "value": [0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1] + }, + { + "type": "double", + "attributes": { + "format.stata": { + "type": "character", + "attributes": {}, + "value": ["%10.0g"] + } + }, + "value": [1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1] + }, + { + "type": "double", + "attributes": { + "format.stata": { + "type": "character", + "attributes": {}, + "value": ["%10.0g"] + } + }, + "value": [4, 4, 4, 3, 3, 3, 3, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 4, 4, 4, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5, 5, 4] + }, + { + "type": "double", + "attributes": { + "format.stata": { + "type": "character", + "attributes": {}, + "value": ["%10.0g"] + } + }, + "value": [4, 4, 1, 1, 2, 1, 4, 2, 2, 4, 4, 3, 3, 3, 4, 4, 4, 1, 2, 1, 1, 2, 2, 4, 2, 1, 2, 2, 4, 6, 8, 2] + } + ] + } + +# do file input works + + Code + stata(testthat::test_path("fixtures/test.do"), mtcars) + Output + Running "C:\\Program Files\\Stata17\\StataMP-64.exe" /e RStata.do + . sum + + Variable | Obs Mean Std. dev. Min Max + -------------+--------------------------------------------------------- + mpg | 32 20.09062 6.026948 10.4 33.9 + cyl | 32 6.1875 1.785922 4 8 + disp | 32 230.7219 123.9387 71.1 472 + hp | 32 146.6875 68.56287 52 335 + drat | 32 3.596563 .5346787 2.76 4.93 + -------------+--------------------------------------------------------- + wt | 32 3.21725 .9784574 1.513 5.424 + qsec | 32 17.84875 1.786943 14.5 22.9 + vs | 32 .4375 .5040161 0 1 + am | 32 .40625 .4989909 0 1 + gear | 32 3.6875 .7378041 3 5 + -------------+--------------------------------------------------------- + carb | 32 2.8125 1.6152 1 8 + . gen test = 1 + +# do file input works with data.out + + Code + stata(testthat::test_path("fixtures/test.do"), mtcars, data.out = TRUE) + Output + Running "C:\\Program Files\\Stata17\\StataMP-64.exe" /e RStata.do + . sum + + Variable | Obs Mean Std. dev. Min Max + -------------+--------------------------------------------------------- + mpg | 32 20.09062 6.026948 10.4 33.9 + cyl | 32 6.1875 1.785922 4 8 + disp | 32 230.7219 123.9387 71.1 472 + hp | 32 146.6875 68.56287 52 335 + drat | 32 3.596563 .5346787 2.76 4.93 + -------------+--------------------------------------------------------- + wt | 32 3.21725 .9784574 1.513 5.424 + qsec | 32 17.84875 1.786943 14.5 22.9 + vs | 32 .4375 .5040161 0 1 + am | 32 .40625 .4989909 0 1 + gear | 32 3.6875 .7378041 3 5 + -------------+--------------------------------------------------------- + carb | 32 2.8125 1.6152 1 8 + . gen test = 1 + +--- + + { + "type": "list", + "attributes": { + "class": { + "type": "character", + "attributes": {}, + "value": ["tbl_df", "tbl", "data.frame"] + }, + "row.names": { + "type": "integer", + "attributes": {}, + "value": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32] + }, + "names": { + "type": "character", + "attributes": {}, + "value": ["mpg", "cyl", "disp", "hp", "drat", "wt", "qsec", "vs", "am", "gear", "carb", "test"] + } + }, + "value": [ + { + "type": "double", + "attributes": { + "format.stata": { + "type": "character", + "attributes": {}, + "value": ["%10.0g"] + } + }, + "value": [21, 21, 22.8, 21.4, 18.7, 18.1, 14.3, 24.4, 22.8, 19.2, 17.8, 16.4, 17.3, 15.2, 10.4, 10.4, 14.7, 32.4, 30.4, 33.9, 21.5, 15.5, 15.2, 13.3, 19.2, 27.3, 26, 30.4, 15.8, 19.7, 15, 21.4] + }, + { + "type": "double", + "attributes": { + "format.stata": { + "type": "character", + "attributes": {}, + "value": ["%10.0g"] + } + }, + "value": [6, 6, 4, 6, 8, 6, 8, 4, 4, 6, 6, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 8, 8, 8, 8, 4, 4, 4, 8, 6, 8, 4] + }, + { + "type": "double", + "attributes": { + "format.stata": { + "type": "character", + "attributes": {}, + "value": ["%10.0g"] + } + }, + "value": [160, 160, 108, 258, 360, 225, 360, 146.7, 140.8, 167.6, 167.6, 275.8, 275.8, 275.8, 472, 460, 440, 78.7, 75.7, 71.1, 120.1, 318, 304, 350, 400, 79, 120.3, 95.1, 351, 145, 301, 121] + }, + { + "type": "double", + "attributes": { + "format.stata": { + "type": "character", + "attributes": {}, + "value": ["%10.0g"] + } + }, + "value": [110, 110, 93, 110, 175, 105, 245, 62, 95, 123, 123, 180, 180, 180, 205, 215, 230, 66, 52, 65, 97, 150, 150, 245, 175, 66, 91, 113, 264, 175, 335, 109] + }, + { + "type": "double", + "attributes": { + "format.stata": { + "type": "character", + "attributes": {}, + "value": ["%10.0g"] + } + }, + "value": [3.9, 3.9, 3.85, 3.08, 3.15, 2.76, 3.21, 3.69, 3.92, 3.92, 3.92, 3.07, 3.07, 3.07, 2.93, 3, 3.23, 4.08, 4.93, 4.22, 3.7, 2.76, 3.15, 3.73, 3.08, 4.08, 4.43, 3.77, 4.22, 3.62, 3.54, 4.11] + }, + { + "type": "double", + "attributes": { + "format.stata": { + "type": "character", + "attributes": {}, + "value": ["%10.0g"] + } + }, + "value": [2.62, 2.875, 2.32, 3.215, 3.44, 3.46, 3.57, 3.19, 3.15, 3.44, 3.44, 4.07, 3.73, 3.78, 5.25, 5.424, 5.345, 2.2, 1.615, 1.835, 2.465, 3.52, 3.435, 3.84, 3.845, 1.935, 2.14, 1.513, 3.17, 2.77, 3.57, 2.78] + }, + { + "type": "double", + "attributes": { + "format.stata": { + "type": "character", + "attributes": {}, + "value": ["%10.0g"] + } + }, + "value": [16.46, 17.02, 18.61, 19.44, 17.02, 20.22, 15.84, 20, 22.9, 18.3, 18.9, 17.4, 17.6, 18, 17.98, 17.82, 17.42, 19.47, 18.52, 19.9, 20.01, 16.87, 17.3, 15.41, 17.05, 18.9, 16.7, 16.9, 14.5, 15.5, 14.6, 18.6] + }, + { + "type": "double", + "attributes": { + "format.stata": { + "type": "character", + "attributes": {}, + "value": ["%10.0g"] + } + }, + "value": [0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1] + }, + { + "type": "double", + "attributes": { + "format.stata": { + "type": "character", + "attributes": {}, + "value": ["%10.0g"] + } + }, + "value": [1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1] + }, + { + "type": "double", + "attributes": { + "format.stata": { + "type": "character", + "attributes": {}, + "value": ["%10.0g"] + } + }, + "value": [4, 4, 4, 3, 3, 3, 3, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 4, 4, 4, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5, 5, 4] + }, + { + "type": "double", + "attributes": { + "format.stata": { + "type": "character", + "attributes": {}, + "value": ["%10.0g"] + } + }, + "value": [4, 4, 1, 1, 2, 1, 4, 2, 2, 4, 4, 3, 3, 3, 4, 4, 4, 1, 2, 1, 1, 2, 2, 4, 2, 1, 2, 2, 4, 6, 8, 2] + }, + { + "type": "double", + "attributes": { + "format.stata": { + "type": "character", + "attributes": {}, + "value": ["%9.0g"] + } + }, + "value": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + } + ] + } + diff --git a/tests/testthat/fixtures/test.do b/tests/testthat/fixtures/test.do new file mode 100644 index 0000000..6d6cb65 --- /dev/null +++ b/tests/testthat/fixtures/test.do @@ -0,0 +1,2 @@ +sum +gen test = 1 diff --git a/tests/testthat/test-stata.R b/tests/testthat/test-stata.R new file mode 100644 index 0000000..7220499 --- /dev/null +++ b/tests/testthat/test-stata.R @@ -0,0 +1,27 @@ +test_that("string cmd input works", { + expect_snapshot(stata("sum", mtcars)) +}) + +test_that("string cmd input works with data.out", { + expect_snapshot(stata("sum", mtcars, data.out = TRUE)) + + expect_snapshot_value( + stata("sum", mtcars, data.out = TRUE), + style = "json2" + ) +}) + +test_that("do file input works", { + expect_snapshot(stata(testthat::test_path("fixtures/test.do"), mtcars)) +}) + +test_that("do file input works with data.out", { + expect_snapshot( + stata(testthat::test_path("fixtures/test.do"), mtcars, data.out = TRUE) + ) + + expect_snapshot_value( + stata(testthat::test_path("fixtures/test.do"), mtcars, data.out = TRUE), + style = "json2" + ) +}) From 80cb54332184ed18cb61761857fc36e69e2efc5c Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Tue, 21 Feb 2023 16:14:52 -0800 Subject: [PATCH 32/38] remove unneeded imports --- DESCRIPTION | 2 -- 1 file changed, 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 52c7ee5..e183075 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -13,8 +13,6 @@ Imports: foreign, haven, readstata13, - tools, - utils, processx, fs, glue From a029e60aeceef6875cc1a9059f264a8d83822e95 Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Tue, 21 Feb 2023 16:15:20 -0800 Subject: [PATCH 33/38] bump version --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index e183075..99ce952 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: RStata Title: A Bit of Glue Between R and Stata -Version: 1.3.2.9003 +Version: 1.3.2.9004 Authors@R: c( person("Eve", "Perry", email = "eve@eveperry.com", role = c("aut", "cre")), person("Luca", "Braglia", email = "lbraglia@gmail.com", role = "aut")) From fdb93c829cdf14122d94a221e7df0f7ed6861a88 Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Tue, 21 Feb 2023 16:24:59 -0800 Subject: [PATCH 34/38] make processx::run quietly --- R/stata.R | 4 ++-- tests/testthat/_snaps/stata.md | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/R/stata.R b/R/stata.R index e6cdc1f..3bab8bd 100644 --- a/R/stata.R +++ b/R/stata.R @@ -253,8 +253,8 @@ stata <- function( processx::run( stata.path, args = stata_args, - echo_cmd = stata.echo, - echo = stata.echo, + echo_cmd = FALSE, + echo = FALSE, stdout = "stdout.txt", stderr_to_stdout = TRUE ) diff --git a/tests/testthat/_snaps/stata.md b/tests/testthat/_snaps/stata.md index 0fedddd..47b8172 100644 --- a/tests/testthat/_snaps/stata.md +++ b/tests/testthat/_snaps/stata.md @@ -3,7 +3,6 @@ Code stata("sum", mtcars) Output - Running "C:\\Program Files\\Stata17\\StataMP-64.exe" /e RStata.do . sum Variable | Obs Mean Std. dev. Min Max @@ -27,7 +26,6 @@ Code stata("sum", mtcars, data.out = TRUE) Output - Running "C:\\Program Files\\Stata17\\StataMP-64.exe" /e RStata.do . sum Variable | Obs Mean Std. dev. Min Max @@ -197,7 +195,6 @@ Code stata(testthat::test_path("fixtures/test.do"), mtcars) Output - Running "C:\\Program Files\\Stata17\\StataMP-64.exe" /e RStata.do . sum Variable | Obs Mean Std. dev. Min Max @@ -222,7 +219,6 @@ Code stata(testthat::test_path("fixtures/test.do"), mtcars, data.out = TRUE) Output - Running "C:\\Program Files\\Stata17\\StataMP-64.exe" /e RStata.do . sum Variable | Obs Mean Std. dev. Min Max From 56efe85d8976e8e5242aa42e710f83c27f0d151c Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Tue, 21 Feb 2023 16:25:05 -0800 Subject: [PATCH 35/38] bump version --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 99ce952..6f869a2 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: RStata Title: A Bit of Glue Between R and Stata -Version: 1.3.2.9004 +Version: 1.3.2.9005 Authors@R: c( person("Eve", "Perry", email = "eve@eveperry.com", role = c("aut", "cre")), person("Luca", "Braglia", email = "lbraglia@gmail.com", role = "aut")) From 387771aedbe1e2c3c5259c548d71372b9d98e9e5 Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Tue, 21 Feb 2023 16:27:59 -0800 Subject: [PATCH 36/38] remove EOL warning --- R/stata.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/stata.R b/R/stata.R index 3bab8bd..dae837c 100644 --- a/R/stata.R +++ b/R/stata.R @@ -258,7 +258,7 @@ stata <- function( stdout = "stdout.txt", stderr_to_stdout = TRUE ) - stataLog <- readLines("stdout.txt") + stataLog <- readLines("stdout.txt", warn = FALSE) if (stataEcho) { if (OS %in% "Windows") From 625ce40f16c6b09aca877568eb5ef4a5020b7000 Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Tue, 21 Feb 2023 16:33:48 -0800 Subject: [PATCH 37/38] bump version --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 6f869a2..d5f240d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: RStata Title: A Bit of Glue Between R and Stata -Version: 1.3.2.9005 +Version: 1.4.0 Authors@R: c( person("Eve", "Perry", email = "eve@eveperry.com", role = c("aut", "cre")), person("Luca", "Braglia", email = "lbraglia@gmail.com", role = "aut")) From 8f050a11fe297ca09371222315b0c03a16c6aeb8 Mon Sep 17 00:00:00 2001 From: Eve Perry Date: Thu, 23 Feb 2023 14:52:18 -0800 Subject: [PATCH 38/38] fix providing path and version as arguments --- DESCRIPTION | 2 +- R/stata.R | 36 ++++++++++++++------------ tests/testthat/_snaps/stata.md | 46 ++++++++++++++++++++++++++++++++++ tests/testthat/test-stata.R | 14 +++++++++++ 4 files changed, 81 insertions(+), 17 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index d5f240d..bb32147 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: RStata Title: A Bit of Glue Between R and Stata -Version: 1.4.0 +Version: 1.4.1 Authors@R: c( person("Eve", "Perry", email = "eve@eveperry.com", role = c("aut", "cre")), person("Luca", "Braglia", email = "lbraglia@gmail.com", role = "aut")) diff --git a/R/stata.R b/R/stata.R index dae837c..06f7837 100644 --- a/R/stata.R +++ b/R/stata.R @@ -93,14 +93,16 @@ stata <- function( if (!is.logical(data.out)) stop("data.out must be logical") - if (is.null(stata.version) & !is.null(getOption("RStata.StataVersion"))) { - stata.version = getOption("RStata.StataVersion") - } - else if (is.null(stata.version) & !grepl("\\D", Sys.getenv("STATA_VERSION"))) { - stata.version = as.integer(Sys.getenv("STATA_VERSION")) - } - else { - stop("You need to specify your Stata version") + if (is.null(stata.version)) { + if (!is.null(getOption("RStata.StataVersion"))) { + stata.version = getOption("RStata.StataVersion") + } + else if (!grepl("\\D", Sys.getenv("STATA_VERSION"))) { + stata.version = as.integer(Sys.getenv("STATA_VERSION")) + } + else { + stop("You need to specify your Stata version") + } } if (!is.numeric(stata.version)) @@ -112,14 +114,16 @@ stata <- function( if (!package %in% c("haven", "readstata13")) stop("package must be either 'haven' or 'readstata13'") - if (is.null(stata.path) & !is.null(getOption("RStata.StataPath"))) { - stata.path = getOption("RStata.StataPath") - } - else if (is.null(stata.path) & Sys.getenv("STATA_PATH") != "") { - stata.path = Sys.getenv("STATA_PATH") - } - else { - stop("You need to set up a Stata path; ?chooseStataBin") + if (is.null(stata.path)) { + if (!is.null(getOption("RStata.StataPath"))) { + stata.path = getOption("RStata.StataPath") + } + else if (Sys.getenv("STATA_PATH") != "") { + stata.path = Sys.getenv("STATA_PATH") + } + else { + stop("You need to set up a Stata path; ?chooseStataBin") + } } OS <- Sys.info()["sysname"] diff --git a/tests/testthat/_snaps/stata.md b/tests/testthat/_snaps/stata.md index 47b8172..fceff82 100644 --- a/tests/testthat/_snaps/stata.md +++ b/tests/testthat/_snaps/stata.md @@ -21,6 +21,52 @@ -------------+--------------------------------------------------------- carb | 32 2.8125 1.6152 1 8 +# version provided as an argument works + + Code + stata("sum", mtcars, stata.version = version) + Output + . sum + + Variable | Obs Mean Std. dev. Min Max + -------------+--------------------------------------------------------- + mpg | 32 20.09062 6.026948 10.4 33.9 + cyl | 32 6.1875 1.785922 4 8 + disp | 32 230.7219 123.9387 71.1 472 + hp | 32 146.6875 68.56287 52 335 + drat | 32 3.596563 .5346787 2.76 4.93 + -------------+--------------------------------------------------------- + wt | 32 3.21725 .9784574 1.513 5.424 + qsec | 32 17.84875 1.786943 14.5 22.9 + vs | 32 .4375 .5040161 0 1 + am | 32 .40625 .4989909 0 1 + gear | 32 3.6875 .7378041 3 5 + -------------+--------------------------------------------------------- + carb | 32 2.8125 1.6152 1 8 + +# path provided as an argument works + + Code + stata("sum", mtcars, stata.path = path) + Output + . sum + + Variable | Obs Mean Std. dev. Min Max + -------------+--------------------------------------------------------- + mpg | 32 20.09062 6.026948 10.4 33.9 + cyl | 32 6.1875 1.785922 4 8 + disp | 32 230.7219 123.9387 71.1 472 + hp | 32 146.6875 68.56287 52 335 + drat | 32 3.596563 .5346787 2.76 4.93 + -------------+--------------------------------------------------------- + wt | 32 3.21725 .9784574 1.513 5.424 + qsec | 32 17.84875 1.786943 14.5 22.9 + vs | 32 .4375 .5040161 0 1 + am | 32 .40625 .4989909 0 1 + gear | 32 3.6875 .7378041 3 5 + -------------+--------------------------------------------------------- + carb | 32 2.8125 1.6152 1 8 + # string cmd input works with data.out Code diff --git a/tests/testthat/test-stata.R b/tests/testthat/test-stata.R index 7220499..71b729c 100644 --- a/tests/testthat/test-stata.R +++ b/tests/testthat/test-stata.R @@ -2,6 +2,20 @@ test_that("string cmd input works", { expect_snapshot(stata("sum", mtcars)) }) +test_that("version provided as an argument works", { + version = as.numeric(Sys.getenv("STATA_VERSION")) + expect_snapshot( + stata("sum", mtcars, stata.version = version) + ) +}) + +test_that("path provided as an argument works", { + path = Sys.getenv("STATA_PATH") + expect_snapshot( + stata("sum", mtcars, stata.path = path) + ) +}) + test_that("string cmd input works with data.out", { expect_snapshot(stata("sum", mtcars, data.out = TRUE))