You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1968 lines
74 KiB
Plaintext
1968 lines
74 KiB
Plaintext
*! savasas Version 2.1 dan.blanchette@duke.edu 12Mar2009
|
|
*! Center of Entrepreneurship and Innovation Duke University's Fuqua School of Business
|
|
** - made savasas able to be run by saswrapper
|
|
** - added some date formats, and made it so that any date format will be kept at least as
|
|
** mmddyy10. format in SAS
|
|
** savasas Version 2.0 dan_blanchette@unc.edu 03Jul2008
|
|
** research computing, unc-ch
|
|
** - created check to make sure user is not trying to create a SAS datafile named with
|
|
** more than 32 characters in the name.
|
|
** - created a check to make sure SAS ran without errors. If not, then messy option is turned on.
|
|
** - fixed the string comparison that generated the the "too many literals" error message
|
|
** when saving long value labels as user-defined SAS formats
|
|
** - fixed all long string comparisons
|
|
** - fixed it so savas does not accidently find an error message in the savasas log
|
|
** - added dataset label saying savasas created dataset on date
|
|
** - added error message that -savasas- cannot be run in Stata batch in Windows
|
|
** - made it so that variable labels can contain macro var references etc.
|
|
** - no longer dealing with sortedby vars since SAS and Stata sort orders are different
|
|
** depending on missing values and DESCENDING sorts
|
|
** savasas Version 1.4 dan_blanchette@unc.edu 29May2007
|
|
** - fixed ability to save special missing values with value label as SAS formats
|
|
** - now label values of negative numbers are also saved as SAS formats
|
|
** - fixed dataset filenames when using the sascode option
|
|
** savasas Version 1.3 dan_blanchette@unc.edu 08Aug2006
|
|
** - fixed it so that vars with non-existent value labels don't throw things off.
|
|
** - fixed situation where value labels with invalid SAS format names were not
|
|
** haiving the rename format assigned to all variables.
|
|
** - added ability to tell savasas where the SAS executable is, but for non-windows os's only.
|
|
** savasas Version 1.2 dan_blanchette@unc.edu 05Aug2005
|
|
** - updated to allow for up to 32 character format value names now possible with SAS 9
|
|
** and maintain Stata 9 value labels up to 32,000 characters to SAS 9 as well.
|
|
** - totally changed how value label names are checked
|
|
** - now using -labvalclone- by Nick Cox included at bottom of file
|
|
** - no longer using -uselabel-
|
|
** - now only trimming off trailing blanks for string variables (no longer trimming leading blanks)
|
|
** savasas Version 1.1 dan_blanchette@unc.edu 04Nov2004
|
|
** - added ability to save data when directory path provided but no SAS file name provided
|
|
** - now allows for SAS file to be saved in a directory using universal filenaming convention e.g."\\\MyServer\sys1\projects\sasf.sas7bdat"
|
|
** - fixed check option so that it only checks the vars and obs specified in the "if and in" if one or both were specified
|
|
** savasas Version 1.1 dan_blanchette@unc.edu 10Sep2004
|
|
** - SAS 9 doesn't support .sd7 as a file extension so -savasas- no longer does for any version of SAS
|
|
** savasas Version 1.1 dan_blanchette@unc.edu 13Jul2004
|
|
** savasas Version 1.1 dan_blanchette@unc.edu 15Nov2003
|
|
** - fixed "keep if in" to select subset of observations
|
|
** and sortedby varnames when longer than 8 characters
|
|
** savasas Version 1.0 dan_blanchette@unc.edu 27Oct2003
|
|
** the carolina population center, unc-ch
|
|
|
|
program define savasas, rclass
|
|
version 8.1 /* using fdasave */
|
|
syntax [varlist] [using/] [in] [if] [, replace sascode Type(string) FORmats udir(string) ///
|
|
MEssy CHeck REName script usas(string) saswrapper ///
|
|
saswrap_data(string) sysjobid(string) ]
|
|
|
|
|
|
|
|
/* log usage of savasas */
|
|
capture which usagelog
|
|
if _rc == 0 {
|
|
usagelog , start type(savas) message(`"savasas using `using' `in' `if' , `replace' `sascode' type(`type') `formats' `messy' `check' `rename' "') `script'
|
|
usagelog , type(savas) message("Input Stata dataset has `c(N)' obs and `c(k)' vars")
|
|
}
|
|
|
|
if "`c(os)'" == "Windows" & "`c(mode)'" == "batch" {
|
|
di as err "{help savasas:savasas} cannot be run in batch mode on Windows"
|
|
/* log usage of savasas */
|
|
capture which usagelog
|
|
if _rc == 0 {
|
|
usagelog , type(savas) uerror(8) etime
|
|
}
|
|
exit 499
|
|
}
|
|
|
|
|
|
capture which fdasave
|
|
if _rc != 0 {
|
|
di `"{error}You need an up to date Stata 8 to run {browse "http://www.cpc.unc.edu/services/computer/presentations/sas_to_stata/savastata.html":savasas}. {help savasas:savasas} {error}uses the {res}fdasave {error}command."'
|
|
|
|
/* log usage of savasas */
|
|
capture which usagelog
|
|
if _rc == 0 {
|
|
usagelog , type(savas) uerror(1) etime
|
|
}
|
|
exit _rc
|
|
}
|
|
|
|
|
|
* FIGURE OUT WHERE SAS EXECUTABLE IS
|
|
* ----------------------------------
|
|
if "`saswrapper'" != "" {
|
|
local quietly quietly
|
|
}
|
|
`quietly' sasexe savasas `sascode' `usas'
|
|
|
|
local wsas `r(wsas)'
|
|
local usas `r(usas)'
|
|
local rver `r(rver)' // version of sas that's being run i.e. "v8", "v9" etc
|
|
|
|
|
|
* FIGURE OUT FILENAME and DIRECTORY
|
|
* ---------------------------------
|
|
// see if there is even one double quote in using
|
|
local subtest : subinstr local using `"""' `""' , count(local cnt)
|
|
if `cnt' != 0 {
|
|
di `"{help savasas} {error}cannot handle directory or file names that contain double quotes. "'
|
|
capture which usagelog
|
|
if _rc == 0 {
|
|
usagelog , type(savas) uerror(2) etime
|
|
}
|
|
exit 499
|
|
}
|
|
|
|
if `: length local using' == 0 { // using is empty so try c(filename)
|
|
local filename "`c(filename)'"
|
|
if `: length local filename' != 0 {
|
|
local subtest : subinstr local filename `"http://"' `""' , count(local cnt)
|
|
if `cnt' != 0 {
|
|
capture _getfilename `"`filename'"' // get error message if only dir in using
|
|
local using `"`r(filename)'"' // make using just the filename
|
|
}
|
|
else { // use the file name and directory of the Stata dataset in memory
|
|
local using="`filename'"
|
|
}
|
|
}
|
|
else if `: length local filename' == 0 {
|
|
di "{error}No file name provided to save data."
|
|
/* log usage of savasas */
|
|
capture which usagelog
|
|
if _rc == 0 {
|
|
usagelog , type(savas) uerror(4) etime
|
|
}
|
|
exit 198
|
|
}
|
|
}
|
|
|
|
// now process using
|
|
/* `: length local using' != 0 */
|
|
|
|
local subtest : subinstr local using `"/"' `""' , count(local cnt)
|
|
if `cnt' != 0 & "`c(os)'" == "Windows" {
|
|
local using : subinstr local using "/" "\" , all
|
|
}
|
|
if "`c(os)'" == "Windows" {
|
|
local dirsep="\"
|
|
}
|
|
else {
|
|
local dirsep="`c(dirsep)'"
|
|
}
|
|
|
|
** if file name is given with directory info too,
|
|
* strip to just file name and to dir location
|
|
// see if using contains directory info
|
|
local subtest : subinstr local using `"`dirsep'"' `""' , count(local cnt)
|
|
if `cnt' != 0 { // Universal naming convention okay here
|
|
capture _getfilename `"`using'"' // get error message if only dir in using
|
|
local filen `"`r(filename)'"'
|
|
if "`filen'" != "" { // dir and filename in using
|
|
local dir : subinstr local using `"`filen'"' `""'
|
|
}
|
|
else if `: length local using' != 0 { // only directory in using
|
|
local dir `"`using'"'
|
|
_getfilename `"`c(filename)'"'
|
|
local filen `"`r(filename)'"'
|
|
}
|
|
}
|
|
else { // no directory given
|
|
local filen="`using'"
|
|
local dir ="`c(pwd)'`dirsep'"
|
|
}
|
|
|
|
|
|
local subtest : subinstr local dir `"/"' `""' , count(local cnt)
|
|
if `cnt' != 0 & "`c(os)'" == "Windows" {
|
|
local dir : subinstr local dir "/" "\" , all
|
|
}
|
|
confirmdir `"`dir'"'
|
|
if _rc != 0 {
|
|
local rc _rc
|
|
di `"{error}The directory "`dir'" does not exist."'
|
|
/* log usage of savasas */
|
|
capture which usagelog
|
|
if _rc == 0 {
|
|
usagelog , type(savas) uerror(16) etime
|
|
}
|
|
exit `rc'
|
|
}
|
|
|
|
|
|
// filen could still be empty
|
|
if `"`filen'"' == `""' {
|
|
di "{error}No file name provided to save data."
|
|
/* log usage of savasas */
|
|
capture which usagelog
|
|
if _rc == 0 {
|
|
usagelog , type(savas) uerror(14) etime
|
|
}
|
|
exit 198
|
|
}
|
|
|
|
|
|
* Data will be changed during program so preserve it so that it will
|
|
* be restored after program finishes running
|
|
preserve
|
|
|
|
|
|
* FIX TYPE
|
|
* --------
|
|
if lower("`type'") == "" | index(lower("`type'"),"sas7") ///
|
|
| index(lower("`type'"),"sas8") ///
|
|
| index(lower("`type'"),"sas9") {
|
|
local type "sas"
|
|
}
|
|
else if lower("`type'") == "ssd01" | lower("`type'") == "sas6" | lower("`type'") == "sd2" {
|
|
local type "sas6"
|
|
}
|
|
else if index(lower("`type'"),"x") | index(lower("`type'"),"tran") {
|
|
local type "sasx"
|
|
}
|
|
|
|
|
|
* IF/IN
|
|
* -----
|
|
|
|
if `: length local if' != 0 | `: length local in' != 0 {
|
|
quietly keep `if' `in'
|
|
}
|
|
|
|
|
|
keep `varlist'
|
|
|
|
if `c(N)' == 0 {
|
|
di as error "{help savasas:savasas} cannot save your dataset because it has no observations. *"
|
|
/* log usage of savasas */
|
|
capture which usagelog
|
|
if _rc == 0 {
|
|
usagelog , type(savas) uerror(5) etime
|
|
}
|
|
exit 2000
|
|
}
|
|
|
|
di _n "{txt}Selected dataset contains {result}`c(N)' {txt}observations and {result}`c(k)' {txt}variables. *"
|
|
|
|
// because savasas needs to test that vars are all unique -rename- is used which
|
|
// temporarily creates the new var plus a tempvar so that adds 2 variables for a bit
|
|
if `c(k)' > 32765 {
|
|
di as error "{help savasas:savasas} can only handle datasets up to 32,765 variables"
|
|
di as error "Your dataset has `c(k)' variables."
|
|
/* log usage of savasas */
|
|
capture which usagelog
|
|
if _rc == 0 {
|
|
usagelog , type(savas) uerror(17) etime
|
|
}
|
|
exit 103
|
|
}
|
|
if `c(k)' > 1000 | `c(N)' > 50000 {
|
|
di _n "{txt}This may take a few minutes. *"
|
|
}
|
|
|
|
|
|
* DATA LIST
|
|
* ---------
|
|
|
|
// extract file extension if there is one
|
|
if index("`filen'",".sas7bdat") & index("`filen'",".sas7bdat") == length("`filen'") - 8 {
|
|
local ext = ".sas7bdat"
|
|
local type = "sas"
|
|
}
|
|
else if index("`filen'",".sd7") & index("`filen'",".sd7") == length("`filen'") - 3 {
|
|
if "`c(os)'" == "Windows" {
|
|
local ext = ".sas7bdat"
|
|
di "{error}Starting with SAS 9 short filename extensions are no longer supported."
|
|
di "{error}Your output SAS datafile will end in .sas7bdat instead of .sd7."
|
|
di "{error}If you are still using an earlier version of SAS, rename the file after it is saved if you like."
|
|
local type = "sas"
|
|
/* local shortfileext="shortfileext" */
|
|
}
|
|
else {
|
|
local ext = ".sas7bdat"
|
|
local type = "sas"
|
|
}
|
|
}
|
|
else if index("`filen'",".ssd01") & index("`filen'",".ssd01") == length("`filen'") - 5 /*
|
|
*/ & "`c(os)'" == "Unix" & "`c(machine_type)'" != "PC" {
|
|
local ext = ".ssd01"
|
|
local type = "sas6"
|
|
}
|
|
else if index("`filen'",".ssd02") & index("`filen'",".ssd02") == length("`filen'") - 5 /*
|
|
*/ & "`c(os)'" == "Unix" & "`c(machine_type)'" == "PC" {
|
|
local ext = ".ssd02"
|
|
local type = "sas6"
|
|
}
|
|
else if index("`filen'",".sd2") & index("`filen'",".sd2") == length("`filen'") - 3 /*
|
|
*/ & "`c(os)'" == "Windows" & "`c(machine_type)'" == "PC" {
|
|
local ext = ".sd2"
|
|
local type = "sas6"
|
|
}
|
|
else if index("`filen'",".xpt") & index("`filen'",".xpt") == length("`filen'") - 3 {
|
|
local ext = ".xpt"
|
|
local type = "sasx"
|
|
}
|
|
else if index("`filen'",".xport") & index("`filen'",".xport") == length("`filen'") - 5 {
|
|
local ext = ".xport"
|
|
local type = "sasx"
|
|
}
|
|
else if index("`filen'",".export") & index("`filen'",".export") == length("`filen'") - 6 {
|
|
local ext = ".export"
|
|
local type = "sasx"
|
|
}
|
|
else if index("`filen'",".expt") & index("`filen'",".exp") == length("`filen'") - 3 {
|
|
local ext = ".exp"
|
|
local type = "sasx"
|
|
}
|
|
else if index("`filen'",".v5x") & index("`filen'",".v5x") == length("`filen'") - 3 {
|
|
local ext = ".v5x"
|
|
local type = "sasx"
|
|
}
|
|
else if index("`filen'",".v6x") & index("`filen'",".v6x") == length("`filen'") - 3 {
|
|
local ext = ".v6x"
|
|
local type = "sasx32 "
|
|
}
|
|
else if index("`filen'",".") {
|
|
local ext = substr("`filen'",index("`filen'","."),length("`filen'"))
|
|
while index("`ext'",".") > 0 {
|
|
local ext = substr("`ext'",index("`ext'",".") + 1,length("`ext'"))
|
|
}
|
|
local ext=".`ext'"
|
|
}
|
|
if index("`filen'",".") {
|
|
local middle=substr("`filen'",1,index("`filen'","`ext'") - 1) /* middle will not end in a period */
|
|
local filen=substr("`filen'",1,index("`filen'",".") - 1)
|
|
local middle=substr("`middle'",length("`filen'")+1,length("`middle'"))
|
|
}
|
|
|
|
if `"`filen'"' == `""' {
|
|
// This should never be the case, but leave in just as a catch
|
|
di `"{error} you have to specify the SAS file name when specifying a file location"'
|
|
/* log usage of savasas */
|
|
capture which usagelog
|
|
if _rc == 0 {
|
|
usagelog , type(savas) uerror(15) etime
|
|
}
|
|
exit 198
|
|
}
|
|
|
|
|
|
****** Check for invalid SAS data file name ************
|
|
local fc = substr("`filen'",1,1)
|
|
// have to use inlist() since the first char is likely a letter
|
|
// and have to split it into two since it can't handle 11 arguments!
|
|
local swn = "0"
|
|
local hsc = "0"
|
|
if inlist("`fc'","0","1","2","3","4") | ///
|
|
inlist("`fc'","5","6","7","8","9") { // name starts with a number
|
|
local swn = "1"
|
|
}
|
|
|
|
if index("`filen'","~") | /// Has a bad character in name
|
|
index("`filen'","!") | ///
|
|
index("`filen'","@") | ///
|
|
index("`filen'","#") | ///
|
|
index("`filen'","$") | ///
|
|
index("`filen'","%") | ///
|
|
index("`filen'","^") | ///
|
|
index("`filen'","&") | ///
|
|
index("`filen'","*") | ///
|
|
index("`filen'","(") | ///
|
|
index("`filen'",")") | ///
|
|
index("`filen'","-") | ///
|
|
index("`filen'","+") | ///
|
|
index("`filen'","=") | ///
|
|
index("`filen'","[") | ///
|
|
index("`filen'","]") | ///
|
|
index("`filen'",":") | ///
|
|
index("`filen'",";") | ///
|
|
index("`filen'","'") | ///
|
|
index("`filen'","<") | ///
|
|
index("`filen'",">") | ///
|
|
index("`filen'","?") | ///
|
|
index("`filen'",",") | ///
|
|
index("`filen'","|") | ///
|
|
index("`filen'"," ") | ///
|
|
index("`filen'","{") | ///
|
|
index("`filen'","}") {
|
|
local hsc = "1"
|
|
}
|
|
|
|
if "`swn'" == "1" | "`hsc'" == "1" {
|
|
if "`rename'" == "" {
|
|
di `"{error}File name {res}"`filen'" {error}is not a valid SAS file name. *"'
|
|
if "`swn'" == "1" {
|
|
di `"{error}SAS file names cannot start with a number. *"'
|
|
}
|
|
if "`hsc'" == "1" {
|
|
di `"{error}SAS file names cannot contain special characters. *"'
|
|
}
|
|
}
|
|
if "`hsc'" == "1" {
|
|
// remove bad characters
|
|
foreach char in ~ ! @ # $ % ^ & * ( ) - + = [ ] : ; ' < > ? , | {
|
|
local filen = subinstr("`filen'","`char'","_",.)
|
|
}
|
|
local filen = subinstr("`filen'","{","_",.)
|
|
local filen = subinstr("`filen'","}","_",.)
|
|
local filen = subinstr("`filen'"," ","_",.)
|
|
|
|
if `"`: subinstr local filen "_" "" , all'"' == "" { // if nothing left, meaning, person used all bad characters
|
|
local filen = "okpopeye"
|
|
}
|
|
} // end of contains bad character
|
|
|
|
if "`swn'" == "1" { // name starts with a number
|
|
if length("`filen'") == 32 {
|
|
local filen = substr("`filen'",2,length("`filen'"))
|
|
local filen = "_`filen'"
|
|
}
|
|
else {
|
|
local filen = "_`filen'"
|
|
}
|
|
} // end of if started with number
|
|
if "`rename'" == "" {
|
|
di `"{error}The {res}rename {error}option will rename it for you to be: {res}"`filen'" "'
|
|
/* log usage of saswrapper */
|
|
capture which usagelog
|
|
if _rc == 0 {
|
|
usagelog , type(savas) uerror(6) etime
|
|
}
|
|
exit 198
|
|
}
|
|
} /* if filen is not a valid SAS data file name */
|
|
|
|
|
|
if "`type'" == "sasx" {
|
|
if !("`ext'" == ".xpt" | /*
|
|
*/ "`ext'" == ".xport" | /*
|
|
*/ "`ext'" == ".export" | /*
|
|
*/ "`ext'" == ".expt" | /*
|
|
*/ "`ext'" == ".trans" | /*
|
|
*/ "`ext'" == ".exp" | /*
|
|
*/ "`ext'" == ".sasx" | /*
|
|
*/ "`ext'" == ".v5x" | /*
|
|
*/ "`ext'" == ".v6x") {
|
|
local middle = "`middle'`ext'"
|
|
local ext = ".xpt"
|
|
}
|
|
if length("`filen'") > 8 & "`rename'" == "" {
|
|
di `"{error}File name {res}"`filen'" {error}is not a valid SAS xport file name. *"'
|
|
di `"{error}SAS xport file names have to be 8 or less characters long. *"'
|
|
local filen = substr("`filen'",1,8)
|
|
di `"{error}The {res}rename {error}option will rename it for you to be: {res}"`filen'" {error}*"'
|
|
/* log usage of savasas */
|
|
capture which usagelog
|
|
if _rc == 0 {
|
|
usagelog , type(savas) uerror(7) etime
|
|
}
|
|
exit 198
|
|
}
|
|
else if length("`filen'") > 8 & "`rename'" != "" {
|
|
local filen = substr("`filen'",1,8)
|
|
}
|
|
|
|
if "`middle'" == ".dta" {
|
|
local middle = ""
|
|
}
|
|
local using = "`macval(dir)'`filen'`middle'"
|
|
local filen = "`filen'"+"`middle'"
|
|
} /* end of if type=sasx */
|
|
else {
|
|
local using = "`macval(dir)'`filen'"
|
|
local ext = ".sas7bdat"
|
|
if "`type'" == "sas6" & "`c(os)'" == "Unix" & "`c(machine_type)'" != "PC" {
|
|
local ext = ".ssd01"
|
|
}
|
|
else if "`type'" == "sas6" & "`c(os)'" == "Unix" & "`c(machine_type)'" == "PC" {
|
|
local ext = ".ssd02"
|
|
}
|
|
else if "`type'" == "sas6" & "`c(os)'" == "Windows" {
|
|
local ext = ".sd2"
|
|
}
|
|
}
|
|
if "`type'" == "sas6" {
|
|
if length("`filen'") > 8 & "`rename'" == "" {
|
|
di `"{error}File name {res}"`filen'" {error}is not a valid SAS version 6 file name. *"'
|
|
di `"{error}SAS version 6 file names have to be 8 or less characters long. *"'
|
|
local filen = substr("`filen'",1,8)
|
|
di `"{error}The {res}rename {error}option will rename it for you to be: {res}"`filen'" {error}*"'
|
|
/* log usage of savasas */
|
|
capture which usagelog
|
|
if _rc == 0 {
|
|
usagelog , type(savas) uerror(8) etime
|
|
}
|
|
exit 198
|
|
}
|
|
else if length("`filen'") > 8 & "`rename'" != "" {
|
|
local filen = substr("`filen'",1,8)
|
|
}
|
|
}
|
|
if "`type'" != "sasx" | "`type'" != "sas6" {
|
|
if length("`filen'") > 32 & "`rename'" == "" {
|
|
di `"{error}File name {res}"`filen'" {error}is not a valid SAS file name. *"'
|
|
di `"{error}SAS file names have to be 32 or less characters long. *"'
|
|
local filen = substr("`filen'",1,32)
|
|
di `"{error}The {res}rename {error}option will rename it for you to be: {res}"`filen'" {error}*"'
|
|
/* log usage of savasas */
|
|
capture which usagelog
|
|
if _rc == 0 {
|
|
usagelog , type(savas) uerror(8) etime
|
|
}
|
|
exit 198
|
|
}
|
|
else if length("`filen'") > 32 & "`rename'" != "" {
|
|
local filen = substr("`filen'",1,32)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
if "`replace'" == "" & "`sascode'" == "" {
|
|
if index(`"`macval(dir)'"',"\") == 1 { // Universal naming doesn't seem to be a problem
|
|
capture confirm file `"`macval(dir)'`filen'`ext'"'
|
|
}
|
|
else {
|
|
capture confirm file `"`macval(dir)'`filen'`ext'"'
|
|
}
|
|
if _rc == 0 {
|
|
di `"{error}The SAS file: "`macval(dir)'`filen'`ext'" already exists."'
|
|
di "{error}Use the {res}replace {error}option if you really want to replace it."
|
|
/* log usage of savasas */
|
|
capture which usagelog
|
|
if _rc == 0 {
|
|
usagelog , type(savas) uerror(9) etime
|
|
}
|
|
exit 602
|
|
}
|
|
} // end of if replace option not used
|
|
|
|
if "`script'" == "" {
|
|
/* set where temp directory is */
|
|
tmpdir
|
|
local tmpdir `"`r(tmpdir)'"'
|
|
|
|
local tfn = subinstr("`c(current_time)'",":","",.)
|
|
local sysjobid = substr("`tfn'",length("`tfn'") - 5,length("`tfn'"))
|
|
local sysjobid = "_`sysjobid'"
|
|
}
|
|
else if "`script'" != "" local tmpdir `"`udir'"'
|
|
|
|
if "`type'" == "sasx" {
|
|
if `c(k)' > 9999 {
|
|
di _n "{error}SAS Xport/Transport files can only handle up to 9,999 variables. *"
|
|
/* log usage of savasas */
|
|
capture which usagelog
|
|
if _rc == 0 {
|
|
usagelog , type(savas) uerror(10) etime
|
|
}
|
|
exit 103
|
|
}
|
|
} /* end of if sasx */
|
|
|
|
|
|
* TEST FOR UNIQUE VARNAMES
|
|
* ------------------------
|
|
|
|
** test that vars will work in SAS transport and version 6 files **
|
|
local j = 1
|
|
local srenamed = 0
|
|
local verror = 0
|
|
local k = 0
|
|
local stop = 0
|
|
local sasvars ""
|
|
foreach var of varlist _all {
|
|
local ovar = "`var'"
|
|
local valid = upper("`var'") /* make all renamed vars uppercase */
|
|
** Test for invalid SAS varnames and **
|
|
** test if variables are not unique for SAS since SAS is case insensitive **
|
|
if upper("`var'") == "_ERROR_" | /* invalid SAS names
|
|
*/ upper("`var'") == "_N_" | /*
|
|
*/ upper("`var'") == "_NUMERIC_" | /*
|
|
*/ upper("`var'") == "_CHARACTER_" | /*
|
|
*/ upper("`var'") == "_ALL_" {
|
|
local verror = 1
|
|
} /* end of if var is an invalid SAS varname */
|
|
if ("`type'" == "sasx" | "`type'" == "sas6") & length("`var'") > 8 {
|
|
local verror = 1
|
|
}
|
|
if "`var'" != upper("`var'") { /* don't check vars that are already upper case */
|
|
capture rename `var' `valid'
|
|
if _rc != 0 {
|
|
local verror = 2
|
|
}
|
|
else {
|
|
local var="`valid'"
|
|
}
|
|
} /* end of don't check if var already upper case */
|
|
if "`rename'" == "" & `verror' >= 1 {
|
|
if `j' == 1 {
|
|
di "{error}Not all Stata variables are valid SAS variables. *"
|
|
di "{error}Specify the {res}rename {error}option for {help savasas:savasas} {error}to rename them. *"
|
|
di "{error}List of variables that need to be renamed: * "
|
|
local stop = 1
|
|
local j = `j'+1
|
|
}
|
|
di "{res}`ovar' *"
|
|
} /* end of if "`rename'" == "" & verror >= 1 */
|
|
else if "`rename'" != "" & `verror' >= 1 {
|
|
local k = 0
|
|
while length("`k'") < 6 { /* make up to 99,999 attempts to rename the variable */
|
|
if ("`type'" == "sasx" | "`type'" == "sas6") & length("`var'") > 8 {
|
|
if `k' == 0 { /* take first 8 characters */
|
|
local valid = upper(substr("`var'",1,8))
|
|
}
|
|
else {
|
|
local valid = upper(substr("`var'",1,8 - length("`k'"))) + "`k'"
|
|
}
|
|
} /* end if sasx or sas6 */
|
|
else {
|
|
if `k' == 0 {
|
|
local k = 1
|
|
}
|
|
local valid = upper(substr("`var'",1,32 - length("`k'"))) + "`k'"
|
|
}
|
|
capture rename `var' `valid'
|
|
if _rc != 0 & length("`k'") == 6 {
|
|
local verror = 1
|
|
}
|
|
else if _rc == 0 {
|
|
if `j' == 1 {
|
|
noi di "The following variables were renamed to valid SAS variable names: * "
|
|
local srenamed = 1
|
|
local j = `j' + 1
|
|
}
|
|
noi di "{res}`ovar' {txt}-> {res}`valid' *"
|
|
local k = "success!"
|
|
} /* end of if _rc == 0 */
|
|
if "`k'" != "success!" {
|
|
local k = `k'+1 /* count attempts to rename vars */
|
|
}
|
|
} /* end of while length(k) < 6 */
|
|
} /* end of if rename and verror */
|
|
if `srenamed' == 0 { /* make sure all vars are valid */
|
|
capture rename `var' `valid'
|
|
}
|
|
if `stop' == 0 {
|
|
if `verror' == 0 {
|
|
local sasvars "`sasvars' `ovar'" /* keep list of vars that have original case if possible */
|
|
}
|
|
else if `verror' >= 1 {
|
|
local sasvars "`sasvars' `valid'" /* keep list of vars that have original case if possible */
|
|
}
|
|
} /* if foreach not stopped */
|
|
local verror = 0
|
|
local srenamed = 0
|
|
} /* end of foreach */
|
|
|
|
if `stop' == 1 { /* This should not be possible. */
|
|
if "`rename'" != "" {
|
|
noi di "{error}ERROR: {help savasas:savasas} was unable to rename variables uniquely to shorter names. *"
|
|
}
|
|
/* log usage of savasas */
|
|
capture which usagelog
|
|
if _rc == 0 {
|
|
usagelog , type(savas) uerror(11) etime
|
|
}
|
|
exit 499
|
|
} /* end of if verror=1 */
|
|
|
|
/* rename all vars so that fdasave won't have to */
|
|
local k = 0
|
|
local stop = 0
|
|
local cvars ""
|
|
foreach valid of varlist _all {
|
|
if length("`valid'") > 8 {
|
|
local k = 0
|
|
while length("`k'") < 6 { /* make up to 99,999 attempts to rename the variable */
|
|
if `k' == 0 { /* take first 8 characters */
|
|
local xptvar = upper(substr("`valid'",1,8))
|
|
}
|
|
else {
|
|
local xptvar = upper(substr("`valid'",1,8 - length("`k'"))) + "`k'"
|
|
}
|
|
capture rename `valid' `xptvar'
|
|
if _rc == 0 {
|
|
local k = "success!"
|
|
} /* end of if _rc == 0 */
|
|
else {
|
|
local k = `k'+1 /* count attempts to rename vars */
|
|
}
|
|
} /* end of while length(k) < 6 */
|
|
} /* end if valid varname > 8 */
|
|
if length("`valid'") <= 8 {
|
|
local xptvar = "`valid'"
|
|
}
|
|
local vt : type `xptvar'
|
|
if index("`vt'","str") {
|
|
local cvars "`cvars' `xptvar'"
|
|
}
|
|
} /* end of foreach */
|
|
|
|
|
|
* FIX STRING VARS
|
|
* ---------------
|
|
// remove trailing blanks in string data
|
|
if "`cvars'" != "" {
|
|
local i = 1
|
|
foreach var of varlist `cvars' {
|
|
if `c(maxstrvarlen)' > 80 {
|
|
quietly compress `var'
|
|
local vt : type `var'
|
|
if real(substr(rtrim("`vt'"),4,length("`vt'"))) > 200 {
|
|
if `i' == 1 {
|
|
// because xport files have a 200 character limit and savasas uses fdasave there is a 200 character limit
|
|
noi di "{help savasas:savasas} {error}can only store the first 200 characters in string variables. *"
|
|
noi di "{error}List of string variables reduced to 200: *"
|
|
local i = `i' + 1
|
|
}
|
|
noi di "{res} `var' *"
|
|
} /* if length > 200 */
|
|
} /* end of if SE dataset */
|
|
quietly replace `var' = substr(rtrim(`var'),1,200) // trim off trailing blanks for all string vars
|
|
} /* end of foreach */
|
|
} /* end of if there are cvars in dataset */
|
|
|
|
local xfilen = substr("`filen'",1,6)
|
|
if `c(k)' > 9999 {
|
|
local vars1 ""
|
|
local vars2 ""
|
|
local vars3 ""
|
|
local vars4 ""
|
|
local i = 0
|
|
local files = 1
|
|
foreach var of varlist _all {
|
|
local i = `i' + 1
|
|
if `i' <= 9999 {
|
|
local vars1 "`vars1' `var'"
|
|
}
|
|
if `i' > 9999 & `i' <= 19998 {
|
|
local vars2 "`vars2' `var'"
|
|
}
|
|
else if `i' > 19998 & `i' <= 29997 {
|
|
local vars3 "`vars3' `var'"
|
|
}
|
|
else if `i' > 29997 {
|
|
local vars4 "`vars4' `var'"
|
|
}
|
|
} /* end of foreach */
|
|
local sysjobid1 = "`sysjobid'1"
|
|
local xfilen1 = substr("`filen'",1,6) + "1"
|
|
if `i' > 9999 {
|
|
local files = 2
|
|
local sysjobid2 = "`sysjobid'2"
|
|
local xfilen2 = substr("`filen'",1,6) + "2"
|
|
}
|
|
if `i' > 19998 {
|
|
local files = 3
|
|
local sysjobid3 = "`sysjobid'3"
|
|
local xfilen3 = substr("`filen'",1,6) + "3"
|
|
}
|
|
if `i' > 29997 {
|
|
local files = 4
|
|
local sysjobid4 = "`sysjobid'4"
|
|
local xfilen4 = substr("`filen'",1,6) + "4"
|
|
}
|
|
} /* if > 9999 vars */
|
|
|
|
if "`type'" == "sas" {
|
|
local eng = "`rver'"
|
|
}
|
|
else if "`type'" == "sas6" {
|
|
local eng = "v6"
|
|
}
|
|
else if "`type'" == "sasx" {
|
|
local eng = "xport"
|
|
}
|
|
|
|
if "`files'" == "" {
|
|
local temp `"`macval(tmpdir)'`sysjobid'"'
|
|
if "`sascode'" == "" { /* save xpt file to temp dir */
|
|
local raw `"`macval(temp)'"'
|
|
}
|
|
else { /* save xpt file to using dir */
|
|
local raw `"`macval(dir)'`filen'"'
|
|
local raw0 `"`macval(dir)'`xfilen'"'
|
|
}
|
|
}
|
|
else {
|
|
foreach file of numlist 1/`files' {
|
|
local temp `"`macval(tmpdir)'`sysjobid'"'
|
|
local raw`file' `"`macval(tmpdir)'`sysjobid`file''"'
|
|
local raw `"`macval(tmpdir)'`sysjobid'"'
|
|
if "`sascode'" != "" { /* save xpt file to using dir */
|
|
local raw`file' `"`macval(dir)'`xfilen`file''"'
|
|
local raw `"`macval(dir)'_`xfilen'"'
|
|
}
|
|
} /* end of foreach file */
|
|
} /* end of else multiple files */
|
|
|
|
|
|
* RUN CHECK REPORT
|
|
* ----------------
|
|
if "`check'" != "" {
|
|
tempfile xpt_ready
|
|
quietly save "`xpt_ready'"
|
|
restore, preserve /* do check on original data */
|
|
if "`script'" == "script" {
|
|
if "`eng'" == "`xport'" {
|
|
/* if xport file then filen may have periods in it */
|
|
local filenx=substr("`filen'",1,index("`filen'",".") - 1)
|
|
log using `"`macval(dir)'`filenx'_STATAcheck.log"', replace
|
|
}
|
|
else if "`eng'" != "`xport'" {
|
|
log using `"`macval(dir)'`filen'_STATAcheck.log"', replace
|
|
}
|
|
} /* if running savasas from script */
|
|
if "`eng'" == "`xport'" {
|
|
di `"Compare results with SAS output: `macval(dir)'`filenx'_SAScheck.lst "'
|
|
global S_FN = "`filenx'"
|
|
}
|
|
else if "`eng'" != "`xport'" {
|
|
di `"Compare results with SAS output: `macval(dir)'`filen'_SAScheck.lst "'
|
|
global S_FN = "`filen'"
|
|
}
|
|
if `srenamed' == 1 { /* if any vars were renamed */
|
|
di "NOTE: The Stata variables here may not match the SAS variables "
|
|
di " because the SAS variables may have been renamed. "
|
|
}
|
|
local five_n = 5
|
|
if _N < 5 {
|
|
local five_n = _N
|
|
}
|
|
// no reason to set more off because if user quits no temp files have been written yet
|
|
// data already subset
|
|
summarize
|
|
describe
|
|
list in 1/`five_n'
|
|
if "`script'" == "script" {
|
|
log close
|
|
}
|
|
use `xpt_ready', clear // though no reason to have to clear since data didn't change!
|
|
} /* end of if check */
|
|
|
|
|
|
* WRITE SAS PROGRAM TO READ IN DATA
|
|
* ---------------------------------
|
|
savasas_sas , dir(`dir') sysjobid(`sysjobid') filen(`filen') raw(`raw') ext(`ext') ///
|
|
engine(`eng') rver(`rver') `check' `sascode' `formats' middle(`middle') ///
|
|
sysjobid1(`sysjobid1') sysjobid2(`sysjobid2') sasvars(`sasvars') ///
|
|
sysjobid3(`sysjobid3') sysjobid4(`sysjobid4') files(`files') ///
|
|
raw0(`raw0') raw1(`raw1') raw2(`raw2') raw3(`raw3') raw4(`raw4') ///
|
|
`shortfileext' xfilen(`xfilen') xfilen1(`xfilen1') xfilen2(`xfilen2') ///
|
|
xfilen3(`xfilen3') xfilen4(`xfilen4') ///
|
|
vars1(`vars1') vars2(`vars2') vars3(`vars3') vars4(`vars4') messy(`messy') ///
|
|
`saswrapper' saswrap_data(`saswrap_data')
|
|
|
|
|
|
* SAVE DATA
|
|
* ---------
|
|
/* min and max values will be tested by fdasave */
|
|
if "`files'" == "" {
|
|
if "`sascode'" == "" {
|
|
quietly fdasave "`raw'", rename vallabfile(none) replace
|
|
}
|
|
else {
|
|
quietly fdasave "`raw0'", rename vallabfile(none) replace
|
|
}
|
|
}
|
|
else if "`files'" != "" {
|
|
foreach file of numlist 1/`files' {
|
|
local nvars : word count "`vars`file''"
|
|
quietly fdasave `vars`file'' using "`raw`file''", rename vallabfile(none) replace
|
|
}
|
|
}
|
|
|
|
if "`sascode'" == "" {
|
|
// if replacing SAS file then see if user has permission to do so
|
|
if index(`"`macval(dir)'"',"\") == 1 { // Universal naming doesn't seem to be a problem
|
|
capture confirm file `"/`macval(dir)'`filen'`ext'"'
|
|
}
|
|
else {
|
|
capture confirm file `"`macval(dir)'`filen'`ext'"'
|
|
}
|
|
if _rc == 0 {
|
|
if "`script'" == "" {
|
|
capture erase `"`macval(dir)'`filen'`ext'"'
|
|
}
|
|
if _rc != 0 {
|
|
di ""
|
|
di `"{error}The SAS file: `macval(dir)'`filen'`ext' cannot be replaced."'
|
|
di `"{error}Check your directory/folder permissions and file permissons."'
|
|
/* log usage of savasas */
|
|
capture which usagelog
|
|
if _rc == 0 {
|
|
usagelog , type(savas) uerror(13) etime
|
|
}
|
|
exit 608
|
|
}
|
|
} /* end of if file exists */
|
|
|
|
* RUN SAS
|
|
* -------
|
|
if "`c(os)'" == "Unix" /* or Linux */ {
|
|
shell "`usas'" "`temp'_infile.sas" -log "`temp'_infile.log"
|
|
run "`temp'_infile_report.do"
|
|
} /* end of if Unix */
|
|
else if "`c(os)'" == "Windows" /* Windows */ {
|
|
shell `wsas' "`temp'_infile.sas" -nologo -log "`temp'_infile.log"
|
|
run "`temp'_infile_report.do"
|
|
} /* end of if Windows */
|
|
sas_rep /* run the SAS report */
|
|
if "`r(sas_rep_error)'" != "" {
|
|
local messy "messy"
|
|
}
|
|
if "`messy'" == "" {
|
|
capture erase "`temp'_infile.sas"
|
|
capture erase "`temp'_infile.log"
|
|
capture erase "`temp'_infile_report.do"
|
|
capture erase "`temp'_formats.txt"
|
|
if "`files'" == "" { // if only 1 xpt file created
|
|
capture erase "`temp'.xpt"
|
|
}
|
|
else {
|
|
foreach file of numlist 0/`files' { // if multiple xpt files created
|
|
capture erase "`raw`file''.xpt"
|
|
}
|
|
} /* end of else */
|
|
} /* end of messy */
|
|
else if "`messy'" != "" & "`script'" == "" {
|
|
di _n "{res}You have requested {help savasas:savasas} not to delete the intermediary files created by savasas:"
|
|
di _n `"in directory: `tmpdir'"'
|
|
dir `"`temp'*"'
|
|
if "`files'" != "" {
|
|
dir `"`raw'*.xpt"'
|
|
}
|
|
|
|
if "`c(console)'" == "" { // not in console mode or batch mode
|
|
if "`c(os)'" != "Windows" { // sysjobid starts with an underscore in savasas
|
|
di `"{res} {stata usesasdel `"`tmpdir'"' `sysjobid' :Click here to erase them all.} "'
|
|
}
|
|
if "`c(os)'" == "Windows" {
|
|
local usesasdeldir : subinstr local tmpdir `":"' `"\\\`= char(58)'"', all
|
|
// sysjobid starts with an underscore in savasas
|
|
di `"{res} {stata usesasdel `"`usesasdeldir'"' `sysjobid' :Click here to erase them all.} "'
|
|
}
|
|
} // not in console or batch mode
|
|
|
|
}
|
|
} /* end of if not wanting only sascode */
|
|
else if "`sascode'" == "sascode" {
|
|
if "`files'" == "" { // if only 1 xpt file created
|
|
if index("`raw0'","\") == 1 { // Universal naming doesn't seem to be a problem
|
|
capture confirm file `"/`macval(raw0)'.xpt"'
|
|
}
|
|
else {
|
|
capture confirm file "`raw0'.xpt"
|
|
}
|
|
if _rc == 0 {
|
|
di `"{txt}The xport data file you requested is: *"'
|
|
di `"{res} "`raw0'.xpt" *"'
|
|
}
|
|
else if _rc != 0 {
|
|
di `"{help savasas:savasas} {error}did not save: *"'
|
|
di `"{txt} "`raw0'.xpt" * "'
|
|
}
|
|
}
|
|
else { // more than one xpt file created
|
|
foreach file of numlist 1/`files' {
|
|
if index("`raw`file''","\") == 1 { // Universal naming doesn't seem to be a problem
|
|
capture confirm file `"/`macval(raw`file')'.xpt"'
|
|
}
|
|
else {
|
|
capture confirm file "`raw`file''.xpt"
|
|
}
|
|
if _rc == 0 {
|
|
if `file' == 1 di `"{txt}The xport data files you requested are: *"'
|
|
di `"{res} "`raw`file''.xpt" *"'
|
|
}
|
|
else if _rc != 0 {
|
|
if `file' == 1 di `"{help savasas:savasas} {error}did not save: *"'
|
|
di `"{txt} "`raw`file''.xpt" * "'
|
|
}
|
|
}
|
|
}
|
|
if index("`raw'","\") == 1 { // Universal naming doesn't seem to be a problem
|
|
capture confirm file "/`macval(raw)'_infile.sas"
|
|
}
|
|
else capture confirm file "`raw'_infile.sas"
|
|
if _rc == 0 {
|
|
di `"{txt}The SAS program to read in the xport data file is: *"'
|
|
di `"{res} "`raw'_infile.sas" *"'
|
|
}
|
|
else if _rc != 0 {
|
|
di `"{help savasas:savasas} {error}did not save:"'
|
|
di `"{txt} "`raw'_infile.sas" * "'
|
|
}
|
|
} /* end of if sascode=sascode */
|
|
|
|
return local sasfile `"`macval(dir)'`filen'`ext'"'
|
|
|
|
restore
|
|
|
|
/* log usage of savasas */
|
|
capture which usagelog
|
|
if _rc == 0 {
|
|
usagelog , type(savas) uerror(0) etime
|
|
}
|
|
|
|
end /* end of savasas */
|
|
|
|
|
|
program define savasas_sas
|
|
syntax [varlist] [, engine(string) rver(string) dir(string) sysjobid(string) ext(string) files(string) ///
|
|
sascode filen(string) CHeck FORmats raw(string) middle(string) ///
|
|
sysjobid1(string) sysjobid2(string) sysjobid3(string) sysjobid4(string) ///
|
|
raw0(string) raw1(string) raw2(string) raw3(string) raw4(string) sasvars(string) ///
|
|
xfilen(string) xfilen1(string) xfilen2(string) xfilen3(string) xfilen4(string) ///
|
|
vars1(string) vars2(string) vars3(string) vars4(string) shortfileext messy(string) ///
|
|
saswrapper saswrap_data(string) ]
|
|
version 8
|
|
|
|
quietly {
|
|
file open sasfile using "`raw'_infile.sas", replace text write
|
|
* DATA LIST
|
|
* ---------
|
|
|
|
if "`sascode'" == "" {
|
|
local in_dset `"`raw'.xpt"'
|
|
}
|
|
else {
|
|
local in_dset `"`raw0'.xpt"'
|
|
}
|
|
|
|
file write sasfile _n `"/********************************************************"' /*
|
|
*/ _n `"** program: `raw'_infiles.sas "' /*
|
|
*/ _n `"** programmer: savasas "' /*
|
|
*/ _n `"** date: `c(current_date)' "' /*
|
|
*/ _n `"** comments: SAS program to read and label: "' /*
|
|
*/ _n `"** `in_dset' "' /*
|
|
*/ _n `"** which contains data from a Stata dataset"' /*
|
|
*/ _n `"********************************************************/"' /*
|
|
*/ _n _n `"options nofmterr nocenter linesize=max;"' _n _n
|
|
|
|
file write sasfile _n `" ** this version of _infile_report.do will be overwritten if all goes well. **; "'
|
|
file write sasfile _n `" data _null_;"' _n `"file "`raw'_infile_report.do"; "' ///
|
|
_n `" put "capture program drop sas_rep"; "' ///
|
|
_n `" put "program define sas_rep, rclass"; "' ///
|
|
_n `" put "di as err "" SAS failed to create `filen' "" "; "' ///
|
|
_n `" put "di as err "" Look at {view `raw'_infile.log:`raw'_infile.log} to see what error occurred. "" "; "'
|
|
if "`messy'" == "" {
|
|
file write sasfile _n `" put "di as err "" The {help savasas:savasas} option messy is now on. "" "; "'
|
|
}
|
|
file write sasfile _n `" put "local sas_rep_error = 1 "; "' ///
|
|
_n `" put "return local sas_rep_error ""\`sas_rep_error\'"" "; "' ///
|
|
_n `" put "end"; "'
|
|
|
|
|
|
if "`engine'" == "v6" {
|
|
file write sasfile _n _n `"libname library v6 "`dir'" `shortfileext'; "' _n _n
|
|
file write sasfile _n _n `"options fmtsearch=(out.`filen'); "' _n _n
|
|
}
|
|
else {
|
|
file write sasfile _n _n `"libname library `engine' "`dir'" `shortfileext'; "' _n _n
|
|
file write sasfile `"options fmtsearch=(out.`filen'); "' _n _n
|
|
}
|
|
|
|
if "`engine'" == "`rver'" | "`engine'" == "v6" {
|
|
file write sasfile `"libname out `engine' "`dir'" `shortfileext' ; "' _n _n
|
|
}
|
|
else if "`engine'" == "xport" {
|
|
file write sasfile `"libname out xport "`macval(dir)'`filen'`ext'"; "' _n _n
|
|
/* if xport file then filen may have periods in it then get rid of them
|
|
* since filen no longer needs them now that libname out defined */
|
|
if index("`filen'",".") {
|
|
local filen=substr("`filen'",1,index("`filen'",".")-1)
|
|
}
|
|
}
|
|
|
|
if `c(k)' <= 9999 {
|
|
if "`sascode'" == "" {
|
|
file write sasfile `"libname raw xport "`raw'.xpt"; "' _n _n
|
|
}
|
|
else {
|
|
file write sasfile `"libname raw xport "`raw0'.xpt"; "' _n _n
|
|
}
|
|
} /* if <= 9999 vars */
|
|
else if `c(k)' > 9999 {
|
|
foreach file of numlist 1/`files' {
|
|
file write sasfile _n _n `"libname raw`file' xport "`raw`file''.xpt"; "' _n _n
|
|
} /* end of foreach file */
|
|
if "`sascode'" == "" {
|
|
file write sasfile `" /* do observational merge to create one big file */ "' /*
|
|
*/ _n `" data `sysjobid'; "' /*
|
|
*/ _n `" merge raw1.`sysjobid1' raw2.`sysjobid2' "'
|
|
if `c(k)' > 19998 {
|
|
file write sasfile `" raw3.`sysjobid3' "'
|
|
if `c(k)' > 29997 {
|
|
file write sasfile `" raw4.`sysjobid4' "'
|
|
} /* end of if > 29997 vars */
|
|
} /* end of if > 19998 vars */
|
|
file write sasfile `";"' _n `"run;"'
|
|
} /* end of if not sascode */
|
|
else {
|
|
file write sasfile `" /* do observational merge to create one big file */ "' /*
|
|
*/ _n `" data `xfilen'; "' /*
|
|
*/ _n `" merge raw1.`xfilen1' raw2.`xfilen2' "'
|
|
if `c(k)' > 19998 {
|
|
file write sasfile `" raw3.`xfilen3' "'
|
|
if `c(k)' > 29997 {
|
|
file write sasfile `" raw4.`xfilen4' "'
|
|
} /* end of if > 29997 vars */
|
|
} /* end of if > 19998 vars */
|
|
file write sasfile `";"' _n `"run;"'
|
|
} /* end of if sascode */
|
|
} /* end of if > 9999 vars */
|
|
|
|
|
|
|
|
* CREATE USER-DEFINED FORMATS FROM VALUE LABELS
|
|
* ---------------------------------------------
|
|
local hasvl 0
|
|
if "`formats'" != "" {
|
|
label dir
|
|
if "`r(names)'" != "" { // dataset has value labels but not sure if they are used in data
|
|
local names `"`r(names)'"'
|
|
local hasvl = 1
|
|
/* establish what is the max length of a user-defined format name
|
|
* based on what version of SAS datafile is desired */
|
|
if index("`engine'","v8") | ///
|
|
index("`engine'","v6") | ///
|
|
index("`engine'","xport") local ml = 8
|
|
else local ml = 32
|
|
|
|
// create a list of all value labels used in data set that are defined
|
|
// a variable can be assigned a label that has not been defined...this is not good
|
|
local all_vlabs `""'
|
|
// create a list of all variables with value labels associated to them
|
|
// that are actually defined
|
|
local lvvars `""'
|
|
foreach var of varlist `varlist' {
|
|
local lbl : value label `var'
|
|
if `"`lbl'"' != "" { // if variable has value label associated to it
|
|
capture label list `lbl' // check to see if exists as defined label
|
|
// if it doesn't give up and move on!
|
|
if _rc == 111 { // label isn't defined
|
|
local lbl ""
|
|
// remove association of label to variable since it isn't defined
|
|
label value `var'
|
|
}
|
|
else { // var has label that is defined
|
|
// all vars with defined labels need to be sent to sav_lvchk
|
|
local lvvars `"`lvvars' `var'"' // create list of vars with value labels
|
|
// label exists and not already listed
|
|
if `: list posof `"`lbl'"' in local(all_vlabs)' == 0 {
|
|
local all_vlabs `"`all_vlabs' `lbl'"'
|
|
}
|
|
}
|
|
}
|
|
} // end of foreach var
|
|
|
|
// drop defined labels that are not associated to variables in current dataset
|
|
foreach lbl of local names {
|
|
if `: list posof `"`lbl'"' in local(all_vlabs)' == 0 {
|
|
label drop `lbl'
|
|
}
|
|
}
|
|
// re-create local macro names now that it's cleaned up
|
|
label dir
|
|
local names `"`r(names)'"'
|
|
} /* end of if dataset has value labels */
|
|
else {
|
|
local hasvl 0
|
|
}
|
|
|
|
if "`r(names)'" != "" { // if dataset really has value labels
|
|
// check and rename value labels if necessary
|
|
capture noisily sav_lvchk, ml(`ml') vars(`lvvars')
|
|
|
|
if _rc == 499 { /* value labels were not uniquely named */
|
|
if "`script'" == "" {
|
|
erase "`raw'_infile.sas"
|
|
}
|
|
/* log usage of savasas */
|
|
capture which usagelog
|
|
if _rc == 0 {
|
|
usagelog , type(savas) uerror(12) etime
|
|
}
|
|
exit 499
|
|
}
|
|
|
|
|
|
if `= real(substr("`rver'",2,length("`rver'")))' > 8 {
|
|
file write sasfile _n `"options NoQuoteLenMax;"' // new option in SAS 9
|
|
}
|
|
else if `c(version)' >= 9 {
|
|
noi di as res _n `"WARNING: Value labels longer than 200 characters may be truncated. *"' _n
|
|
}
|
|
|
|
sav_labs_data `varlist', fhandle(sasfile) ml(`ml') filen(`filen') raw(`"`raw'"')
|
|
|
|
} /* end of if dataset really has value labels */
|
|
else {
|
|
local hasvl 0
|
|
}
|
|
} /* end of if formats to be created from value labels */
|
|
|
|
if "`engine'" != "xport" {
|
|
file write sasfile _n _n `"data out.`filen' "' ///
|
|
`" (label= "-savasas- created dataset on %sysfunc(date(),date9.)" "'
|
|
if "`engine'" != "v6" {
|
|
file write sasfile `" rename=("' _n
|
|
local i = 1
|
|
tokenize "`sasvars'" /* good SAS variable names */
|
|
foreach var of varlist _all {
|
|
file write sasfile `" `var' = ``i''"'
|
|
if mod(`i',5) == 0 {
|
|
file write sasfile _n
|
|
}
|
|
local i = `i' + 1
|
|
} /* end of foreach */
|
|
file write sasfile _n `" ));"' _n `" length "'
|
|
} /* if not v6 engine */
|
|
else if "`engine'" == "v6" { /* no need to rename vars for v6 files */
|
|
file write sasfile _n `");"' _n `" length "'
|
|
}
|
|
}
|
|
else if "`engine'" == "xport" { /* don't need vars renamed or sort info */
|
|
file write sasfile _n _n `"data out.`filen' "' ///
|
|
`" (label= "-savasas- created dataset on %sysfunc(date(),date9.)" );"' _n `" length "'
|
|
}
|
|
|
|
|
|
* SET VARS TO MINIMUM DATATYPE
|
|
* ----------------------------
|
|
compress /* so says Loren */
|
|
|
|
local j 1
|
|
local verror = 0
|
|
foreach var of varlist `varlist' {
|
|
local storage : type `var'
|
|
if index("`storage'","str") == 0 {
|
|
if ("`storage'" == "float") | ("`storage'" == "double") {
|
|
local len = 8
|
|
}
|
|
else if "`storage'" == "byte" {
|
|
local len = 3
|
|
}
|
|
else if "`storage'" == "int" {
|
|
local len = 4
|
|
}
|
|
else if "`storage'" == "long" {
|
|
local len = 6
|
|
}
|
|
file write sasfile `" `var' `len'"'
|
|
} /* end of if not string */
|
|
else if index("`storage'","str") == 1 {
|
|
local len = substr("`storage'",4,length("`storage'"))
|
|
file write sasfile `" `var' $`len'"'
|
|
}
|
|
if (mod(`j',8) == 0) { /* print 8 vars per line */
|
|
file write sasfile _n
|
|
}
|
|
local j = `j' + 1
|
|
} /* end of foreach */
|
|
if `verror' == 1 {
|
|
file close sasfile
|
|
exit 499
|
|
}
|
|
if `c(k)' <= 9999 {
|
|
if "`sascode'" == "" {
|
|
file write sasfile _n `" ;;;"' _n `" set raw.`sysjobid'; "' _n
|
|
}
|
|
else {
|
|
file write sasfile _n `" ;;;"' _n `" set raw.`xfilen'; "' _n
|
|
}
|
|
}
|
|
else if `c(k)' > 9999 {
|
|
if "`sascode'" == "" {
|
|
file write sasfile _n `" ;;;"' _n `" set `sysjobid';"' _n
|
|
}
|
|
else {
|
|
file write sasfile _n `" ;;;"' _n `" set `xfilen';"' _n
|
|
}
|
|
}
|
|
|
|
* VARIABLE LABEL
|
|
* --------------
|
|
|
|
file write sasfile _n _n " LABEL "
|
|
foreach var of varlist `varlist' {
|
|
local varlab : variable label `var'
|
|
// add spaces around varlab so that varlab can start with a right quote and contain a right parentheses
|
|
local varlab = trim(`" `varlab' "')
|
|
if `"`varlab'"' != "" {
|
|
// add spaces around varlab so that varlab can start with a right quote and contain a right parentheses
|
|
if index(`" `varlab' "',`"'"') {
|
|
/* substitute 2 single quotes for one single quote */
|
|
local varlab = subinstr(`" `varlab' "',`"'"',`"''"',.)
|
|
}
|
|
// enclosing the var label in single quotes keeps macro vars or calls
|
|
// to macros from happening
|
|
if index(`" `varlab' "',"'") == 2 {
|
|
/* if varlab starts with a single right quote, add space
|
|
* before it so that it doesn't end the left compound quote in the
|
|
* file write of varlabel. escaping it doesn't escape it */
|
|
file write sasfile _n (upper("`var'")) `"=' `varlab' ' "'
|
|
}
|
|
else if substr(`"`varlab'"',length(`"`varlab'"'),1) == `"""' {
|
|
// add a space at the end to separate the last double quote and the right quote
|
|
file write sasfile _n (upper(" `var'")) `"='`varlab' ' "'
|
|
}
|
|
else {
|
|
file write sasfile _n (upper(" `var'")) `"='`varlab'' "'
|
|
}
|
|
} /* end of if varlab exists */
|
|
} /* end of foreach */
|
|
file write sasfile _n " ;;;"
|
|
|
|
* ASSIGN VALUE LABELS
|
|
* -------------------
|
|
if `hasvl' == 1 {
|
|
file write sasfile _n _n "format "
|
|
local j 1
|
|
foreach var of varlist `varlist' {
|
|
local lbl : value label `var'
|
|
capture label list `lbl' // check to see if exists as defined label
|
|
// if it doesn't, then give up and move on!
|
|
if _rc == 111 local lbl ""
|
|
if `"`lbl'"' != "" {
|
|
file write sasfile " `var' `lbl'."
|
|
if (mod(`j',5) == 0) { /* print 5 vars per line */
|
|
file write sasfile _n
|
|
}
|
|
local j = `j' + 1
|
|
} /* end of if var has label */
|
|
} /* end foreach */
|
|
|
|
file write sasfile _n " ;;;"
|
|
} /* end of if variables have value labels */
|
|
|
|
|
|
* NON-USER DEFINED FORMATS
|
|
* ------------------------
|
|
|
|
file write sasfile _n _n "format "
|
|
|
|
local j 1
|
|
foreach var of varlist `varlist' {
|
|
local storage : type `var'
|
|
local fmt : format `var'
|
|
if "`formats'" != "" {
|
|
local lbl : value label `var'
|
|
capture label list `lbl' // check to see if exists as defined label
|
|
// if it doesn't give up and move on!
|
|
if _rc == 111 local lbl ""
|
|
}
|
|
local format = ""
|
|
/* only assign formats to vars with no value label */
|
|
if !index("`storage'"',"str") & `"`fmt'"' != "" & `"`lbl'"' == "" {
|
|
|
|
if substr(`"`fmt'"',length(`"`fmt'"'),1) == "f" {
|
|
local format = substr("`fmt'",2,length("`fmt'") - 2)
|
|
if `format' > 18 {
|
|
local format = "18."
|
|
}
|
|
local format = "`format'"
|
|
}
|
|
else if substr(`"`fmt'"',length(`"`fmt'"')-1,2) == "0g" {
|
|
local format = substr(`"`fmt'"',2,index(`"`fmt'"',".") - 2) + "."
|
|
if `format' > 18 {
|
|
local format = "18."
|
|
}
|
|
local format = "BEST" + "`format'"
|
|
}
|
|
else if substr(`"`fmt'"',length(`"`fmt'"'),1) == "c" {
|
|
local format = substr(`"`fmt'"',2,length(`"`fmt'"',".") - 3)
|
|
if `format' > 18 {
|
|
local format = "18."
|
|
}
|
|
local format = "COMMA" + "`format'"
|
|
}
|
|
else if inlist(`"`fmt'"',"%dDlY","%dDmY","%dDMY", "%ddlY","%ddmY","%ddMY") {
|
|
local format = "DATE7."
|
|
}
|
|
else if inlist(`"`fmt'"',"%dDlCY","%dDmCY","%dDMCY", "%ddlCY","%ddmCY","%ddMCY") {
|
|
local format = "DATE9."
|
|
}
|
|
else if `"`fmt'"' == "%dD/N/Y" {
|
|
local format = "DDMMYY8."
|
|
}
|
|
else if `"`fmt'"' == "%dD/N/CY" {
|
|
local format = "DDMMYY10."
|
|
}
|
|
else if `"`fmt'"' == "%dN/D/Y" {
|
|
local format = "MMDDYY8."
|
|
}
|
|
else if `"`fmt'"' == "%dN/D/CY" {
|
|
local format = "MMDDYY10."
|
|
}
|
|
else if `"`fmt'"' == "%dYND" {
|
|
local format = "YYMMDD6."
|
|
}
|
|
else if `"`fmt'"' == "%dY-N-D" {
|
|
local format = "YYMMDD10."
|
|
}
|
|
else if `"`fmt'"' == "%dCY-N-D" {
|
|
local format = "YYMMDD10."
|
|
}
|
|
else if `"`fmt'"' == "%dD" {
|
|
local format = "DAY."
|
|
}
|
|
else if `"`fmt'"' == "%dl" {
|
|
local format = "MONTH."
|
|
}
|
|
else if `"`fmt'"' == "%dY" {
|
|
local format = "YEAR2."
|
|
}
|
|
else if `"`fmt'"' == "%dCY" {
|
|
local format = "YEAR4."
|
|
}
|
|
else if `"`fmt'"' == "%dM" {
|
|
local format = "MONNAME."
|
|
}
|
|
else if `"`fmt'"' == "%dlY" {
|
|
local format = "MONYY5."
|
|
}
|
|
else if `"`fmt'"' == "%dlCY" {
|
|
local format = "MONYY7."
|
|
}
|
|
else if `"`fmt'"' == "%dd" {
|
|
local format = "WEEKDAY."
|
|
}
|
|
else if `"`fmt'"' == "%d" {
|
|
local format = "WORDDATE."
|
|
}
|
|
else if `"`fmt'"' == "%dYl" {
|
|
local format = "YYMON5."
|
|
}
|
|
else if `"`fmt'"' == "%dCYl" {
|
|
local format = "YYMON7."
|
|
}
|
|
else if index(`"`fmt'"',"%d") == 1 { // the catch-all date format
|
|
local format = "MMDDYY10."
|
|
}
|
|
|
|
file write sasfile " `var' `format'"
|
|
if (mod(`j',5) == 0) { /* print 5 vars per line */
|
|
file write sasfile _n
|
|
}
|
|
local j = `j' + 1
|
|
} /* end of if var has a format */
|
|
} /* end foreach */
|
|
|
|
file write sasfile _n " ;;; " _n "run;" _n ///
|
|
" %let lib_error=&syserr.; " _n _n
|
|
|
|
|
|
* CHECK SAS DATA
|
|
* --------------
|
|
if "`check'" != "" {
|
|
noi di " "
|
|
noi di `" You have requested savasas to generate a check file from SAS. * "'
|
|
if "`engine'" == "xport" {
|
|
noi di `" The file is: "{res}`macval(dir)'`filen'`middle'_SAScheck.lst" * "'
|
|
}
|
|
else {
|
|
noi di `" The file is: "{res}`macval(dir)'`filen'_SAScheck.lst" * "'
|
|
}
|
|
noi di " "
|
|
if "`engine'" == "xport" {
|
|
file write sasfile _n `"proc printto print= "`macval(dir)'`filen'`middle'_SAScheck.lst" new; "' ///
|
|
_n _n `" title "data= `macval(dir)'`filen'`middle': Compare results with Stata output."; "'
|
|
}
|
|
else if "`engine'" != "xport" {
|
|
file write sasfile _n `"proc printto print= "`macval(dir)'`filen'_SAScheck.lst" new; "' ///
|
|
_n _n `" title "data= `macval(dir)'`filen': Compare results with Stata output."; "'
|
|
}
|
|
file write sasfile _n _n `" proc means data= out.`filen'; run;"' ///
|
|
_n _n `" proc contents data= out.`filen'; run;"' ///
|
|
_n _n `" proc print data= out.`filen' (obs=5); run; "' ///
|
|
_n _n `" proc printto; run; "' _n
|
|
} /* end of checking */
|
|
|
|
if "`sascode'" == "" {
|
|
local out = "out."
|
|
if "`engine'" == "xport" {
|
|
file write sasfile _n `"data `filen';"' _n `" set out.`filen'; "' _n "run;" _n
|
|
local out="work."
|
|
}
|
|
|
|
file write sasfile _n `"data test;"' _n `"call symput("N",compress(put(___lo___,10.)));"' ///
|
|
_n `" stop; "' _n `"set `out'`filen' nobs=___lo___; "' _n `" run; "' _n ///
|
|
_n `"proc contents data= test out= contents noprint ;"' _n `"run; "' _n ///
|
|
_n `"data _null_;"' _n `"call symput("nvars",compress(put(___lo___,5.)));"' ///
|
|
_n `"stop;"' _n `"set contents nobs=___lo___;"' _n `"run; "' _n ///
|
|
_n _n `"data _null_;"' _n `"file "`raw'_infile_report.do"; "' ///
|
|
_n `" put "capture program drop sas_rep"; "' ///
|
|
_n `" put "program define sas_rep"; "'
|
|
|
|
if "`engine'" == "`rver'" {
|
|
local ext = ".sas7bdat"
|
|
}
|
|
else if "`engine'" == "v6" {
|
|
if "`c(os)'" == "Unix" & "`c(machine_type)'" != "PC" { /* Unix */
|
|
local ext = ".ssd01"
|
|
}
|
|
if "`c(os)'" == "Unix" & "`c(machine_type)'" == "PC" { /* Linux */
|
|
local ext = ".ssd02"
|
|
}
|
|
else {
|
|
local ext = ".sd2" /* Windows */
|
|
}
|
|
} /* end of if v6 */
|
|
else if "`engine'" == "xport" {
|
|
local filen = "`filen'" + "`middle'"
|
|
} /* end of if xport */
|
|
|
|
if index("`macval(dir)'","\") == 1 { // Universal naming is an issue here since
|
|
// this code writes code. Stata sees / as a dir separator no matter the OS.
|
|
// so add / since one \ will be lost
|
|
local cdir `"/`macval(dir)'"'
|
|
file write sasfile _n /*
|
|
*/ _n `"put "capture confirm file ""`macval(cdir)'`filen'`ext'"" "; "' _n
|
|
}
|
|
else {
|
|
file write sasfile _n /*
|
|
*/ _n `"put "capture confirm file ""`macval(dir)'`filen'`ext'"" "; "' _n
|
|
}
|
|
file write sasfile _n ///
|
|
_n `"put " if _rc == 0 { "; "' _n ///
|
|
_n `"put " di ""{help savasas:savasas} {txt}successfully saved the SAS file: *"""; "'_n
|
|
if "`saswrapper'" == "" {
|
|
file write sasfile _n ///
|
|
_n `"put " di "" {res}`macval(dir)'`filen'`ext' {txt} *"""; "' _n
|
|
}
|
|
else {
|
|
file write sasfile _n ///
|
|
_n `"put " di "" {res}`saswrap_data' in the SAS WORK library """; "' _n
|
|
}
|
|
file write sasfile _n ///
|
|
_n `"put " di ""{res}SAS &sysver. {txt}reports that the dataset has {res}&N {txt}observations "' _n ///
|
|
`"and {res}&nvars {txt}variables. *"" "; "' _n ///
|
|
_n `"put "capture which usagelog"; "' _n ///
|
|
_n `"put " if _rc == 0 {"; "' _n ///
|
|
_n `"put " usagelog , type(savas) message(""&sysuserid. Output SAS dataset has &N obs and &nvars vars"")"; "' _n ///
|
|
_n `"put " }"; "' _n ///
|
|
_n `"put "}"; "' _n
|
|
|
|
|
|
file write sasfile _n `" put "end"; "' _n `"run;"' _n
|
|
} /* end of if sascode not wanted */
|
|
|
|
|
|
* CLOSE SASFILE
|
|
* -------------
|
|
file close sasfile
|
|
if `hasvl' == 1 & "`saswrapper'" == "" {
|
|
noi di _n "{txt}SAS formats catalog file has been created: *"
|
|
if "`engine'" == "`rver'" & "`shortfileext'" == "" {
|
|
noi di " {res}`macval(dir)'`filen'.sas7bcat *"
|
|
}
|
|
else if "`engine'" == "v8" & "`shortfileext'" != "" {
|
|
noi di " {res}`macval(dir)'`filen'.sc7 *"
|
|
}
|
|
else if "`engine'" == "v6" & "`c(os)'" == "Windows" {
|
|
noi di " {res}`macval(dir)'`filen'.sc2 *"
|
|
}
|
|
else if "`engine'" == "v6" & "`c(os)'" == "Unix" & "`c(machine_type)'" == "PC" { /* Linux */
|
|
noi di " {res}`macval(dir)'`filen'.sct02 *"
|
|
}
|
|
else if "`engine'" == "v6" & "`c(os)'" == "Unix" & "`c(machine_type)'" != "PC" { /* Unix */
|
|
noi di " {res}`macval(dir)'`filen'.sct01 *"
|
|
}
|
|
noi di "{txt}Add the following SAS statements to the SAS program that *"
|
|
noi di "{txt}uses {res}`macval(dir)'`filen'`ext' {txt}: * "
|
|
noi di `"{res} libname in `engine' "`macval(dir)'" `shortfileext'; {txt}*"'
|
|
noi di `"{res} options fmtsearch=(in.`filen'); {txt}*"'
|
|
}
|
|
} /* end of quietly */
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
* CHECK THAT STATA VALUE LABEL NAMES CAN BE MADE INTO SAS FORMAT NAMES
|
|
* IF SO, THEN RENAME
|
|
* --------------------------------------------------------------------
|
|
|
|
program sav_lvchk
|
|
version 8
|
|
syntax , ml(integer) vars(varlist)
|
|
|
|
local ren 0
|
|
local flag5 = 0
|
|
local bad_labs `" "'
|
|
local names `"`r(names)'"'
|
|
local renamed ""
|
|
local orig_names ""
|
|
|
|
|
|
foreach var of varlist `vars' {
|
|
local lbl : value label `var'
|
|
local nlbl = ""
|
|
// check if that label has not already been renamed
|
|
if `: list posof "`lbl'" in orig_name' == 0 {
|
|
// check if label ends in a number--illegal in SAS
|
|
if length("`lbl'") <= `= `ml'-1' & ( ///
|
|
substr("`lbl'",length("`lbl'"),1) == "1" | ///
|
|
substr("`lbl'",length("`lbl'"),1) == "2" | ///
|
|
substr("`lbl'",length("`lbl'"),1) == "3" | ///
|
|
substr("`lbl'",length("`lbl'"),1) == "4" | ///
|
|
substr("`lbl'",length("`lbl'"),1) == "5" | ///
|
|
substr("`lbl'",length("`lbl'"),1) == "6" | ///
|
|
substr("`lbl'",length("`lbl'"),1) == "7" | ///
|
|
substr("`lbl'",length("`lbl'"),1) == "8" | ///
|
|
substr("`lbl'",length("`lbl'"),1) == "9" | ///
|
|
substr("`lbl'",length("`lbl'"),1) == "0") {
|
|
local nlbl = "`lbl'_"
|
|
}
|
|
else if length("`lbl'") == `ml' {
|
|
if substr("`lbl'",`ml',1) == "1" {
|
|
local nlbl = substr("`lbl'",1,`= `ml' - 1') + "z"
|
|
}
|
|
else if substr("`lbl'",`ml',1) == "2" {
|
|
local nlbl = substr("`lbl'",1,`= `ml' - 1') + "y"
|
|
}
|
|
else if substr("`lbl'",`ml',1) == "3" {
|
|
local nlbl = substr("`lbl'",1,`= `ml' - 1') + "x"
|
|
}
|
|
else if substr("`lbl'",`ml',1) == "4" {
|
|
local nlbl = substr("`lbl'",1,`= `ml' - 1') + "w"
|
|
}
|
|
else if substr("`lbl'",`ml',1) == "5" {
|
|
local nlbl = substr("`lbl'",1,`= `ml' - 1') + "v"
|
|
}
|
|
else if substr("`lbl'",`ml',1) == "6" {
|
|
local nlbl = substr("`lbl'",1,`= `ml' - 1') + "u"
|
|
}
|
|
else if substr("`lbl'",`ml',1) == "7" {
|
|
local nlbl = substr("`lbl'",1,`= `ml' - 1') + "t"
|
|
}
|
|
else if substr("`lbl'",`ml',1) == "8" {
|
|
local nlbl = substr("`lbl'",1,`= `ml' - 1') + "s"
|
|
}
|
|
else if substr("`lbl'",`ml',1) == "9" {
|
|
local nlbl = substr("`lbl'",1,`= `ml' - 1') + "r"
|
|
}
|
|
else if substr("`lbl'",`ml',1) == "0" {
|
|
local nlbl = substr("`lbl'",1,`= `ml' - 1') + "q"
|
|
}
|
|
} // end of if label `ml' characters long and ends in a number
|
|
else if length("`lbl'") > `ml' {
|
|
local nlbl = substr("`lbl'",1,`= `ml' - 1') + "_"
|
|
}
|
|
// check that defined value label not a valid SAS format
|
|
else if inlist(lower("`lbl'"), ///
|
|
"best" ,"binary" ,"comma" ,"commax" ,"d" ,"date" ,"datetime") {
|
|
local nlbl = substr("`lbl'",1,`= `ml' - 1') + "_"
|
|
}
|
|
else if inlist(lower("`lbl'"), ///
|
|
"dateampm","day" ,"ddmmyy" ,"dollar" ,"dollarx" ,"downame" ,"e" ) {
|
|
local nlbl = substr("`lbl'",1,`= `ml' - 1') + "_"
|
|
}
|
|
else if inlist(lower("`lbl'"), ///
|
|
"eurdfdd" ,"eurdfde" ,"eurdfdn" ,"eurdfdt" ,"eurdfdwn","eurdfmn" ,"eurdfmy" ) {
|
|
local nlbl = substr("`lbl'",1,`= `ml' - 1') + "_"
|
|
}
|
|
else if inlist(lower("`lbl'"), ///
|
|
"eurdfwdx","eurdfwkx","float" ,"fract" ,"hex" ,"hhmm" ,"hour" ) {
|
|
local nlbl = substr("`lbl'",1,`= `ml' - 1') + "_"
|
|
}
|
|
else if inlist(lower("`lbl'"), ///
|
|
"ib" ,"ibr" ,"ieee" ,"julday" ,"julian" ,"percent" ,"minguo" ) {
|
|
local nlbl = substr("`lbl'",1,`= `ml' - 1') + "_"
|
|
}
|
|
else if inlist(lower("`lbl'"), ///
|
|
"mmddyy" ,"mmss" ,"mmyy" ,"monname" ,"month" ,"monyy" ,"negparen") {
|
|
local nlbl = substr("`lbl'",1,`= `ml' - 1') + "_"
|
|
}
|
|
else if inlist(lower("`lbl'"), ///
|
|
"nengo" ,"numx" ,"octal" ,"pd" ,"pdjulg" ,"pdjuli" ,"pib" ) {
|
|
local nlbl = substr("`lbl'",1,`= `ml' - 1') + "_"
|
|
}
|
|
else if inlist(lower("`lbl'"), ///
|
|
"pibr" ,"pk" ,"pvalue" ,"qtr" ,"qtrr" ,"rb" ,"roman" ) {
|
|
local nlbl = substr("`lbl'",1,`= `ml' - 1') + "_"
|
|
}
|
|
else if inlist(lower("`lbl'"), ///
|
|
"s370ff" ,"s370fib" ,"s370fibu","s370fpd" ,"s370fpdu","s370fpib","s370frb" ) {
|
|
local nlbl = substr("`lbl'",1,`= `ml' - 1') + "_"
|
|
}
|
|
else if inlist(lower("`lbl'"), ///
|
|
"s370fzd" ,"s370fzdl","s370fzds","s370fzdt","s370fzdu","ssn" ,"time" ) {
|
|
local nlbl = substr("`lbl'",1,`= `ml' - 1') + "_"
|
|
}
|
|
else if inlist(lower("`lbl'"), ///
|
|
"timeampm","tod" ,"weekdate","weekdatx","weekday" ,"worddate","worddatx") {
|
|
local nlbl = substr("`lbl'",1,`= `ml' - 1') + "_"
|
|
}
|
|
else if inlist(lower("`lbl'"), ///
|
|
"wordf" ,"words" ,"year" ,"yen" ,"yymm" ,"yymmdd" ,"yymon" ) {
|
|
local nlbl = substr("`lbl'",1,`= `ml' - 1') + "_"
|
|
}
|
|
else if inlist(lower("`lbl'"), ///
|
|
"yyq" ,"yyqr" ,"z" ,"zd", "f") {
|
|
local nlbl = substr("`lbl'",1,`= `ml' - 1') + "_"
|
|
}
|
|
|
|
// re-assign value labels using SAS-ok value label names
|
|
if `"`nlbl'"' != "" & `"`nlbl'"' != `"`lbl'"' {
|
|
local ren = `ren' + 1 // count ones needed to be renamed
|
|
if `: list posof "`nlbl'" in names' > 0 { // nlbl already an existing label
|
|
local flag5 = 1
|
|
// make a list of bad value label names
|
|
if `: list posof "`nlbl'" in bad_labs' == 0 { // add if not already in list
|
|
local bad_labs `"`bad_labs'`nlbl' "'
|
|
}
|
|
}
|
|
else { // label okay to be renamed
|
|
// assign new label to variable
|
|
label value `var' `nlbl'
|
|
if `ren' == 1 {
|
|
noi di _n "{txt}NOTE: SAS format names cannot be more than `ml' characters long, *"
|
|
noi di " {txt}cannot end in a number, nor be a SAS reserved format name. *"
|
|
noi di "{txt}NOTE: {res}The following value label(s) will have the following *"
|
|
noi di " SAS format value name: *"
|
|
noi di as result `"Original"' _col(20)`"Renamed *"'
|
|
noi di as result `"--------"' _col(20)`"------- *"'
|
|
}
|
|
if `: list posof "`nlbl'" in renamed' == 0 { // if not already listed
|
|
noi di as result `"`lbl'"' _col(20)`"`nlbl' *"'
|
|
local orig_names "`orig_names'`lbl' " // add to list
|
|
local renamed "`renamed'`nlbl' " // add to list
|
|
// Use Nick Cox's labvalclone command to do just that!
|
|
labvalclone `lbl' `nlbl'
|
|
}
|
|
}
|
|
}
|
|
} // end of if value label has not already been renamed
|
|
else {
|
|
// use existing label
|
|
local nlbl "`: word `: list posof "`lbl'" in orig_name' of `renamed''"
|
|
label `var' `nlbl'
|
|
}
|
|
|
|
} /* end of foreach */
|
|
// now that all vars have been processed, drop the labels that were cloned
|
|
foreach lbl of local orig_names {
|
|
label drop `lbl'
|
|
}
|
|
if `flag5' == 1 {
|
|
foreach lab of local bad_labs {
|
|
noi di "{error}NOTE: {res}value label `lab' {error}could not be uniquely renamed. *"
|
|
}
|
|
noi di "{help savasas:savasas} {error}has stopped processing. *"
|
|
|
|
file close sasfile
|
|
|
|
error 499
|
|
}
|
|
end
|
|
|
|
|
|
* WRITE OUT USER-DEFINED FORMATS AS A SAS DATASET SO THAT LONG FORMATS ARE NOT A PROBLEM
|
|
* --------------------------------------------------------------------------------------
|
|
|
|
program sav_labs_data, rclass
|
|
version 8
|
|
syntax [varlist], fhandle(string) ml(integer) filen(string) raw(string)
|
|
|
|
// need to re-create r(names) since sav_lvchk may have renamed labels
|
|
label dir
|
|
if "`r(names)'" != "" { // dataset has value labels. the check before sav_lvchk
|
|
// has assured that they are used in data
|
|
|
|
if `ml' == 8 local maxlablen = 256
|
|
else local maxlablen = 32000
|
|
local lrecl =`maxlablen' + 75
|
|
|
|
tempfile test
|
|
file write `fhandle' _n `"data formats;"'
|
|
file write `fhandle' _n `"length fmtname $`ml' start end 8 label $`maxlablen';"'
|
|
file write `fhandle' _n `"infile "`raw'_formats.txt" lrecl=`lrecl' truncover ; "'
|
|
file write `fhandle' _n `"input fmtname 1-32 start 34-53 end 55-74 label 76-`maxlablen';"'
|
|
|
|
file open sas_formats using "`raw'_formats.txt", replace text write
|
|
local lab2long = 0
|
|
|
|
local names `r(names)'
|
|
foreach lab of local names {
|
|
tempname lab_in
|
|
tempfile lab_file
|
|
label save `lab' using `"`lab_file'"', replace
|
|
file open `lab_in' using `"`lab_file'"', r // read-only
|
|
file read `lab_in' lab_line // load first line of file to local macro var lab_line
|
|
local lvs ""
|
|
local n_lvs = 0 // number of label values
|
|
// read lab_file one line at a time
|
|
// and count how many lines there are
|
|
while r(eof) == 0 {
|
|
local lv : word 4 of `lab_line'
|
|
if `lv' < . local n_lvs = `n_lvs' + 1
|
|
// collect label values into one macro
|
|
local lvs `"`lvs' `lv'"'
|
|
file read `lab_in' lab_line
|
|
} // end of while eof loop
|
|
file close `lab_in'
|
|
label list `lab' // just to figure out if has special missings or not
|
|
if `r(min)' == . & `r(max)' == . { // only has special missing values
|
|
local fora `"each lv in `c(alpha)'"' // really: "foreach lv in `c(alpha)'"
|
|
local fors `"fora"'
|
|
}
|
|
else if `r(hasemiss)' == 1 { // has both
|
|
local forn `"val lvn = 1/`n_lvs'"' // really: "forval lvn = 1/`n_lvs'"
|
|
local fora `"each lv in `c(alpha)'"' // really: "foreach lv in `c(alpha)'"
|
|
local fors `"forn fora"'
|
|
}
|
|
else if `r(min)' != . & `r(max)' != . { // has no special missing values
|
|
local forn `"val lvn = 1/`n_lvs'"' // really: "forval lvn = 1/`n_lvs'"
|
|
local fors `"forn"'
|
|
}
|
|
foreach each_val of local fors {
|
|
local multi_l = 0
|
|
local write_lab = 0
|
|
// this only works if there is always a loop to process
|
|
for``each_val'' { // adding the "for" help Stata not freak out when this section isn't run
|
|
if "`each_val'" == "forn" { // for numeric lists look for ranges
|
|
local lv : word `lvn' of `lvs'
|
|
local label : label `lab' `lv'
|
|
// `label' equals the number if no label assigned
|
|
// which shouldn't happen now that only processing label values
|
|
if `: list local(label) == local(lv)' == 0 { // if value has a label
|
|
local nlv : word `= `lvn'+1' of `lvs'
|
|
local nlabel "" // no label by default
|
|
if `= `lvn'+1' <= `n_lvs' { // : word > n words of string is invalid syntax
|
|
local nlabel : label `lab' `nlv'
|
|
}
|
|
local plabel "" // no label by default
|
|
if `lvn' != 1 { // : word 0 of string is invalid syntax
|
|
local plv : word `= `lvn'-1' of `lvs'
|
|
local plabel : label `lab' `plv'
|
|
}
|
|
local npl = 0
|
|
if `: list local(label) == local(nlabel)' == 1 {
|
|
if `: list local(label) == local(plabel)' == 0 {
|
|
if ( "`= `lv'+1'" == "`nlv'" ) { // nlv is in quotes since it might = " "
|
|
local multi_l = 1
|
|
local start = `lv'
|
|
local npl = 1
|
|
}
|
|
}
|
|
}
|
|
if `npl' == 0 & `: list local(label) == local(nlabel)' == 0 {
|
|
if `multi_l' == 1 {
|
|
local write_lab = 1
|
|
local multi_l = 0
|
|
}
|
|
else { // no range
|
|
local write_lab = 1
|
|
local start = `lv'
|
|
}
|
|
}
|
|
else if `: list local(label) == local(nlabel)' == 1 & /// {
|
|
( "`= `lv'+1'" != "`nlv'" ) { // no range because not continuous values
|
|
local write_lab = 1
|
|
local start = `lv'
|
|
} // end of checking for ranges
|
|
if `write_lab' == 1 {
|
|
local write_lab = 0
|
|
if `: length local label' > `maxlablen' {
|
|
local lab2long = 1
|
|
}
|
|
// `macval(label)' keeps dollar signs or `something'
|
|
// from being evaluated, $ being more likely
|
|
// fmtname start end label
|
|
file write sas_formats _n _col(0)`"`lab'"' _col(34)`"`start'"' _col(57)`"`lv'"' _col(81)`"`macval(label)'"'
|
|
}
|
|
} // end of if value has a label
|
|
} // end of if for is forn
|
|
else { // process fora list which is only special missings
|
|
local label : label `lab' .`lv'
|
|
// `label' equals the special missing value if no label assigned
|
|
// ( there is length issue here since only checking for ".a", ".b" etc
|
|
if "`label'" != ".`lv'" { // if value has a label
|
|
if `: length local label' > `maxlablen' {
|
|
local lab2long = 1
|
|
}
|
|
// `macval(label)' keeps dollar signs or `something'
|
|
// from being evaluated, $ being more likely
|
|
// fmtname start end label
|
|
file write sas_formats _n _col(0)`"`lab'"' _col(34)`".`lv'"' _col(57)`".`lv'"' _col(81)`"`macval(label)'"'
|
|
}
|
|
} // end if fora loop
|
|
} // end of for``each_val'' loop
|
|
} // end of fors loop
|
|
} // end foreach lab of local names
|
|
|
|
|
|
file write `fhandle' _n `"run; "' _n
|
|
file write `fhandle' _n _n `"proc format library= library.`filen' cntlin= work.formats(where= (fmtname ^= ""));"'
|
|
file write `fhandle' _n `"run; quit;"'
|
|
// macro tests if SAS could create new formats catalog and erases it and does it again if SAS
|
|
// initially is not able to due to catalog file having been created for a different OS
|
|
file write `fhandle' _n _n `"%macro redo;"'
|
|
file write `fhandle' _n `" ** Check for this error message:"'
|
|
file write `fhandle' _n `" * upcase(error:) File LIBRARY.`filen'.CATALOG was created for a different operating system. **;"'
|
|
file write `fhandle' _n `" %if &syserr. = 3000 %then %do;"'
|
|
file write `fhandle' _n `" proc datasets library= library "'
|
|
file write `fhandle' _n `" memtype= catalog "'
|
|
file write `fhandle' _n `" nodetails nolist nowarn;"'
|
|
file write `fhandle' _n `" delete `filen';"'
|
|
file write `fhandle' _n `" run;"'
|
|
file write `fhandle' _n `" ** now try it! **;"'
|
|
file write `fhandle' _n `" proc format library= library.`filen' cntlin= work.formats(where= (fmtname ^= ""));"'
|
|
file write `fhandle' _n `" run; quit;"'
|
|
file write `fhandle' _n `" %end;"'
|
|
file write `fhandle' _n `"%mend redo;"'
|
|
file write `fhandle' _n `"%redo;"'
|
|
|
|
if `lab2long' == 1 {
|
|
di as error "WARNING: at least one value label was truncated because it was longer than `maxlablen' characters"
|
|
}
|
|
// capture file close sas_formats since "``for'' {" throws stata off but this is now fixed so not a problem?
|
|
capture file close sas_formats
|
|
} // end of if dataset has value labels (condition is probably not needed)
|
|
|
|
end
|
|
|
|
|
|
*! NJC 1.1.1 3 Nov 2002
|
|
* NJC 1.1.0 1 Nov 2002
|
|
program def labvalclone
|
|
version 7
|
|
args old new garbage
|
|
if "`old'" == "" | "`new'" == "" | "`garbage'" != "" {
|
|
di as err "syntax is: " /*
|
|
*/ as txt "labvalclone {it:vallblname newvallblname}"
|
|
exit 198
|
|
}
|
|
if "`old'" == "label" | "`old'" == "define" {
|
|
di as err "won't work if {txt:`old'} is existing value label name"
|
|
exit 198
|
|
}
|
|
capture label list `new' // check to see if exists as defined label
|
|
if _rc == 0 {
|
|
di as err "value labels {txt:`new'} already exist"
|
|
exit 198
|
|
}
|
|
|
|
tempfile file1 file2
|
|
tempname in out
|
|
|
|
qui label save `old' using `"`file1'"'
|
|
file open `in' using `"`file1'"', r
|
|
file open `out' using `"`file2'"', w
|
|
file read `in' line
|
|
|
|
while r(eof) == 0 {
|
|
local line: subinstr local line "`old'" "`new'"
|
|
file write `out' `"`line'"' _n
|
|
file read `in' line
|
|
}
|
|
file close `out'
|
|
|
|
qui do `"`file2'"'
|
|
end
|
|
|
|
exit
|
|
|