As I was looking through a log file from
D:\SAS\XXX\Lev1\SASMain\BatchServer\Logs
I saw these two lines
NOTE: Libref TESTLIB successfully assigned from logical server.
NOTE: Libref TESTLIB was successfully assigned as follows:
Engine: XXXX
Physical Name: XX.XXX.XXX.XX
What is the difference between or meaning behind these two lines?
The first line tells you that the library has been assigned as a pre-assigned library from metadata. If you look at SAS Management Console>Data Library Manager>TESTLIB>properties>Options>Advanced Options>"Library is Pre-Assigned". If this checbox is ticked, you will see the first line, given that the user has "Read Metadata" permissions on the library.
The second line comes if the library is explicitly assigned in the code. DI Studio will create libname statements in the code if the library is not pre-assigned.
Assuming that you found the two lines right next to each other:
The first line is telling you that SAS encountered no problems trying to assign the libref TESTLIB. If you tried to assign a libref to a non-existent folder / server, or you didn't have the necessary access (etc...) you'd get an error message instead of this line.
The second line is telling you a bit more about the libref that was assigned. In your case this includes the IP address of the server and SAS libname engine used. Depending on the value of XXXX, it's possible that in this case you're connecting to a different DBMS.
Related
Using Stata, I define a local macro (macro_name) as a variable (macro_variable) in one data file.
After reading in a new file (in the same do file), I'm no longer able to reference that macro.
Instead, I receive the error:
. di `macro_name'
macro_variable not found
I am learning how to use macros, so please bear with me. However, shouldn't I be able to still display or call on that macro in a single do file even if I load in a new data set?
For example:
use "newdata.dta", clear
This problem occurs regardless of whether I define the macro as a global or local. Additionally, I attempted to solve the problem by creating a separate locals.do file that include in the preamble of my master do file as:
include locals.do
But, I still receive the error listed above.
Do macros (local or global) disappear immediately upon reading in a new file? That doesn't seem right based on what I've read.
Thanks in advance for any clarification.
Consider the following, which points to the source of your problem, and in the last command, reproduces precisely the error message you received.
. do "/var/folders/xr/lm5ccr996k7dspxs35yqzyt80000gp/T//SD08491.000000"
. local macro_name macro_variable
. macro list _macro_name
_macro_name: macro_variable
. display "`macro_name'"
macro_variable
. display `macro_name'
macro_variable not found
r(111);
end of do-file
Added in edit: The above was run from the do-file editor window. When I instead launch Stata and paste the four commands into the command window, running them a line at a time, the following are what results.
. local macro_name macro_variable
. macro list _macro_name
_macro_name: macro_variable
. display "`macro_name'"
macro_variable
. display `macro_name'
macro_variable not found
r(111);
.
At the risk of over-explaining, the point to my original answer is that the error message the displayed in the original post, and in the final command in both of my examples, was due to the failure to include quotation marks in the display command, which caused display to believe that "macro_variable", which was the value assigned to the local macro "macro_name" was not a character string constant, but rather a variable name or scalar, and display was unable to locate a variable or scalar by that name.
Let me add as a bonus explanation that the use of locals.do described in the original post has no hope of working, because local macros are local to the do-file in which they are executed, and vanish at the termination of that do-file. In particular, if you submit a local command by selecting a subset of the lines in the do-file editor window, those lines are copied into a temporary do-file and the values of the local macros vanish at the termination of the temporary do-file.
Generalizing what I wrote in my comment above to Nick:
Macros only maintain the connection between the variable/varlist assigned to a macro name and, therefore, the variable/varlist to which the macro's name refers to must be in memory (i.e. the dataset that contains the variable/varlist has to be in memory) in order to access it via the macro.
Assigning a variable/varlist to a macro does not persist the actual value(s)/element(s) in memory, but rather maintain the connection between the variable/varlist and the macro name assigned to it/them.
I have the following code that is running inside a macro. When it is run in interactive mode, it runs absolutely fine, no errors or warning. That was the case for last two year.
The same code has now been deployed in batch mode and it generates a warning WARNING: Apparent symbolic reference FIRSTRECCOUNT not resolved. and no value assigned to macro variable.
My question is, does anyone have any ideas why batch mode and interactive mode would behave differently?
Here some more information:
The dataset is being created and it is in work library.
The dataset does get opened by data step.
`firstreccount' doesn't get initialiased anywhere else in the program
I have search sas community. There is a topic here, but I don't have the same errors in batch initilisation as described in the answer.
Detailed information on the warning but it doesn't explain by it would work in interactive mode, but not in batch mode.
.
1735 %LET FIRSTSET = work.dataset1;
1744 DATA _NULL_;
1745 IF 0 THEN
1746 SET &FIRSTSET NOBS=X;
1747 CALL SYMPUT('FIRSTRECCOUNT' ,X);
1748 STOP;
1749 RUN;
1755 DATA _NULL_;
1756 IF 0 THEN
1757 SET &SECONDSET NOBS=X;
1758 CALL SYMPUT('SECONDRECOUNT' ,X);
1759 STOP;
1760 RUN;
WARNING: Apparent symbolic reference FIRSTRECCOUNT not resolved.
Update:
So I have attempted to replicate the error by copying the code with warning into a separate scheduled flow, but it didn't cause any errors at all.
By the way, the original job was deployed from SAS DI studio. I have checked all lines in user written code nodes and made sure that the length was within 80 characters as recommended by #RawFocus, #RobertPentridge, but it didn't solve the issue.
As recomended by #data_null_ I have checked VALIDVARNAME and it was different between interactive (value of "any") and batch mode (value of "V7") but changing these hasn't made any difference.
I have rewritted the logic to get the number of observations by calling attr for an open dataset. This eliminated the warning, but program would still fail with warning popping out in different places. It made me think Robert Partridge is correct. At the same time, I got an error that a macro not being resolved. The macro was inserted by DI studio to collect performance MI even that the job wasn't meant to be collecting MI. This made me think that SAS DI studio is not generating code correctly when deploying it, so I manually edited the deployed code to remove offending macro call and I also spotted that there was one line of code with MD5 function that was too long on one line because of a number of parameters being passed to it, so I inserted some white space. And finally the problem was fixed!!
I still need to do something about the job because when it will get redeployed from SAS DI, it will generate the same errors again. I don't have time to look into this further at the moment.
Conclusion: what you write in SAS DI and what gets deployed could be slightly different which could cause syntax parse to throw errors in random places. So I will mark Robert's answer as correct because it got me closer to solving the problem then any other answer.
The problem could be happening above the code snippet you pasted. The parser got into a funk earlier, and ended up issuing warning about code that is perfectly fine.
Check to make sure that no code within a macro is longer that ~160 chars on a single line. I try to keep my code well below that but long lines of code can run fine interactively and fail in batch - particularly when inside of a macro.
I expect your program has some small error above that does not cause SAS to go into syntax check mode when run interactively but does cause SAS to set obs to 0 and enter syntax check mode when run in batch.
One possibility is the limit (in batch mode) of the length of a line in your submitted SAS program:
See: http://support.sas.com/kb/15/883.html
Which version of SAS are you running?
Here is a sample program .do file, sampleprog.do:
program sampleprog
egen newVar = group (`1' `2')
end
How can I post it on my website (or dropbox), so that other people could install it to their Stata like this?
net from http://www.mywebsite.com/sampleprog.do
*** or may be like like this:
ssc install ...
I read the documentation about stata.toc...but I did not quite get it. What files should I upload and should it be one folder or what?
(PS: I definitely can simply email the .do file but this is not an option in my case.)
Here is a full explanation of how to share program or data files with others using your own website. I tried using Dropbox, but Stata 12 appears to have issues with https, which is the protocol for all Dropbox public links. If you want to use Dropbox, I recommend creating a shared folder that will sync on your collaborators' machines. The rest of this answer assumes you have a website serving pages over http or are using Stata 13, which supports https.
If this is a one-time thing, you can skip the rest of this answer by putting the file on your website and telling your collaborator to type:
. copy http://your-site.com/ado/program.ado program.ado
That will copy the ado file at the specified url into the user's current directory. If you want to provide information about your files, plan on sharing with multiple people and need to maintain/document a set files, read on!
Step 1 Create a folder on your website to hold the programs. I will call mine ado/
Step 2 Add the program files, help files, and data files you want to share. For this example, I have created a simple ado file called unique.ado with the following contents:
********************************************** unique.ado
capture program drop unique
program define unique
*! Count and number observations within group defined by varlist
* Example: unique person_id, obs(prow) tobs(pcount) sortby(time)
* to count and number rows by a variable called person_id
syntax varlist, obs(name) tobs(name) [sortby(varlist)]
bys `varlist' (`sortby') : gen long `obs' = _n
bys `varlist' (`sortby') : gen long `tobs' = _N
la var `obs' "Number of this row within `varlist' group."
la var `tobs' "Total number of rows with identical `varlist' values."
end
Step 3 Create a file called stata.toc to describe the files you wish to share. Here is mine:
********************************************** stata.toc
v 3
d Program to count observations by group
p unique [The unique.ado program for counting observations by group]
These files can be complicated. There are many features I won't cover here, but you can read this documentation to learn more.
Step 4 Create a package file for each of the packages defined by the lines in stata.toc that start with the letter p. Here is my package file for the unique package defined above:
********************************************** unique.pkg
v 3
d unique
d Program to count observations by group
d Distribution-Date: 28 June 2012
f unique.ado
Your directory now looks like this:
ado/
stata.toc
unique.ado
unique.pkg
Step 5 Use the site! Here are the commands to enter.
. net from http://example.com/ado/
. net describe unique
. net install unique
Here is what you'll see after entering the first command:
-----------------------------------------------------------------------------------
http://www.example.com/ado/
Program to count observations by group
-----------------------------------------------------------------------------------
PACKAGES you could -net describe-:
unique [The unique.ado program for counting observations by group]
-----------------------------------------------------------------------------------
The second command will tell you more about the package net describe unique:
---------------------------------------------------------------------------------------
package unique from http://www.example.com/ado
---------------------------------------------------------------------------------------
TITLE
unique
DESCRIPTION/AUTHOR(S)
Program to count observations by group
Distribution-Date: 28 June 2012
INSTALLATION FILES (type net install unique)
unique.ado
---------------------------------------------------------------------------------------
The third command will install the package net install unique:
checking unique consistency and verifying not already installed...
installing into /Users/cpoliquin/Library/Application Support/Stata/ado/plus/...
installation complete.
EDIT
See Nick's comments in the answer below. I intended this example to be simple and I don't expect other people to use this program. If you plan on submitting things to Stata Journal or SSC then his comments certainly apply! I hope this answer can serve as a decent tutorial for those confused by the official documentation.
This will be too long for a comment, so it is going to be an extra answer.
Your example uses the program name unique. If you search unique, all (or in Stata 13, search unique) you will find that a user-written program with the same name has been installed on SSC since 1998. This will create a clash of names for your users if (and only if) they attempt to use your program and also that earlier program. The more general advice is to search to see if a program name is already in use to try to avoid these problems.
Specifically, although you may just be using your unique as an arbitrary example, note that it contains bugs. An int doesn't contain enough bits to hold observation numbers exactly for large datasets. Also, as a matter of style, unique can change the sort order of your data, which is widely considered to be poor data management style.
Your example concerns dissemination of a program file without an accompanying help file. Suffice it to say that the SSC site would never accept such a program and the Stata Journal would not even review a paper based on such a submission before a help file was written to accompany it. Including explanatory comments with the code may be sufficient for your personal practices, but it falls below general Stata standards.
Stata 13 now supports https. See http://www.stata.com/manuals13/u.pdf, Section 3.6.
In short, I appreciate that you are trying to explain how to do something, but it is already well documented, and explicitly and implicitly some of your recommendations are below community standards.
I've just started learning SAS because I'm required to use it for a statistics course. For this course, the university provides SAS 9.2 through their virtual-machine setup: I make a reservation in their system, they generate a VM on one of their servers, and I connect to the VM using Microsoft's Remote Desktop client. The virtual machines are generated and erased per session; settings are reset every time, and files must be stored on my client computer (which is accessible in the VM by a UNC path).
Within this setup, when I open a program file stored on my laptop, I've only been able to access the accompanying data files (each stored in the same folder as the program) either by hardcoding the full path or by updating the "current folder" setting at the beginning of each session. The first is problematic because it means the program won't run anywhere else - in particular, when I email it to the professor. The second is inconvenient, because browsing to this particular UNC path is time consuming, and I already have to browse to the same path to open the program file.
I want to make this easier by programmatically setting the current folder to the folder containing the program. Then I could just open the file and get to work. I've found some examples of getting the filename of the program file, of getting the path to a fileref, and of (link limit exceeded) setting the current folder, but I haven't been able to combine them in the right way. Please connect the dots for me.
To programmatically change the Windows current directory from SAS, you can use the X command, which is what really happens when you use the "Change current folder" dialog box:
x 'cd "\\computername\share name\folder"';
You can also do this using the SYSTEM data step function, a method I prefer because you get a return code (but more typing of course):
data _null_;
rc = system( 'cd "\\computername\share name\folder"' );
if rc = 0
then putlog 'Command successful';
else putlog 'Command failed';
run;
Note the UNC path is surrounded with double-quotes, which is necessary if the path contains blanks.
Of course, this still requires you to manually type in the command, but it might be something you could add to the program source code. If your VM environment allowed you to maintain some permanent presence on the server, you could save this command into a start-up file.
I would ask your professor for advice; if you are working with data given to you as part of your class, you may only need to send just the source code. On the other hand, if you are creating output data as part of your assignment, your professor might want your to deliver source code and SAS data sets. Surely he or she will have some procedure.
Complete Answer:
SAS's obtuse notation requires some strange delimiter fiddling to combine my partial solution (finding the path) with #Bob Duell's partial solution (setting the current folder). There seem to be two key rules involved:
&var is expanded in double-quoted strings ("&var"), but not single-quoted strings ('&var')
Quotes in &var are not treated as delimiters after expansion
So the solution is to compute a string of the quoted path (where the quotes are part of the string), and expand that within a double-quoted parameter to X or SYSTEM:
%let qsrc=%str(%")&src%str(%");
X "cd &qsrc"
It's not required to store the string, both &src and &qsrc can be expanded in-place, which yields a single statement solution:
X "cd %str(%")%substr(%sysget(SAS_EXECFILEPATH),1,%eval(%length(%sysget(SAS_EXECFILEPATH))-%length(%sysget(SAS_EXECFILENAME))))%str(%")";
This executes correctly, but breaks the syntax coloring in the GUI. Within a string, %str(%") and "" both expand to ", so replacing %str(%") with "" both executes correctly and is colored correctly in the GUI:
X "cd ""%substr(%sysget(SAS_EXECFILEPATH),1,%eval(%length(%sysget(SAS_EXECFILEPATH))-%length(%sysget(SAS_EXECFILENAME))))""";
This inherits the limitation that it only works when SAS_EXECFILEPATH and SAS_EXECFILENAME are defined, which is the case when running from within the Windows GUI editor. It's also subject to any limitations on in the "cd" command, which SAS intercepts rather than invoking the Windows command line. I expect it will fail on paths containing quotes.
A partial answer: One way to get the containing folder from the filename of the program file
Spread out & logging steps:
/* Find PathName of folder containing program */
%let FullName=%sysget(SAS_EXECFILEPATH);
%put FullName: &FullName.;
%let FullLen=%length(&FullName);
%put FullLen: &FullLen.;
%let BaseName=%sysget(SAS_EXECFILENAME);
%put BaseName: &BaseName.;
%let BaseLen=%length(&BaseName);
%put BaseLen: &BaseLen.;
%let PathLen=%eval(&FullLen.-&BaseLen.);
%put PathLen: &PathLen.;
%let PathName=%substr(&FullName,1,&PathLen);
%put PathName: &PathName.;
Consolidated & silent:
/* Find src folder */
%let src=%substr(%sysget(SAS_EXECFILEPATH),1,%eval(%length(%sysget(SAS_EXECFILEPATH))-%length(%sysget(SAS_EXECFILENAME))));
This only works when SAS_EXECFILEPATH and SAS_EXECFILENAME are defined, and it's not clear when that is. It does work when using the Windows GUI editor.
I am running SAS version 8.1 on the OpenVMS 8.3 platform. I have tried 2 different ways to import a csv data file and cant seem to get either of them to work properly. It would be great if anyone has any ideas as to what I may be doing wrong. This seems like a rather simple thing to do.
CSV file
SSID,field1,......(etc)
AA9999999,043844,.......(etc)
Method A -- This seems to "almost" work.
DATA JU2_DAT;
INFILE STD_JU2 DSD LRECL=1024 TRUNCOVER FIRSTOBS=2;
INPUT ID $
field1 $
For some reason the last character of the ID field is cut off...instead of getting 9 characters I am getting only 8.
Method B
PROC IMPORT DATAFILE=STD_JU2 OUT=JU2_DAT DBMS=CSV ;
GETNAMES=YES;
This method just doesn't seem to run at all. It pegs the CPU at 100% and when I terminate the process I have the following errors in the LOG. This one baffles me as I am not running this in any kind of windowing environment.
ERROR: Cannot open X display. Check display name/server access authorization.
+ERROR: Cannot open X display. Check display name/server access authorization.
+ERROR: Cannot open X display. Check display name/server access authorization.
+
+
ERROR: Device does not support full-screen.
+ERROR: Device does not support full-screen.
+ERROR: Device does not support full-screen.
ERROR: Named item not found in list.
+ERROR: Named item not found in list.
+ERROR: Named item not found in list.
I would try adding an informat to your input statement. The default length is 8 chars. Use the colon modifier which will cause SAS to read for :$X. chars OR until a delimiter is encountered.
INFILE STD_JU2 DSD LRECL=1024 TRUNCOVER FIRSTOBS=2;
INPUT ID :$9.
field1 $
I have never used OpenVMS, but I have seen the error message:
ERROR: Cannot open X display. Check display name/server access authorization.
or something similar under Unix when running without an X server. The solution was to invoke SAS with the -nodms (or possibly -nodmr) command line option.