SAS: how to use the table column with special character $ - sas

I use sas manipulate some database tables. There is a column "CDR$UNPIVOT$SKEY" in one table. I can't direct use this column name in data step or Proc SQL, even i change the option of VALIDVARNAME=ANY.
Is there a way to direct use such column name?
Thank you!

Yep. You are very close now. All you need is to address it using its literal format.
option validvarname=any;
data want;
'CDR$UNPIVOT$SKEY'n = 'I can see now';
run;
proc print data=want;run;

Related

How to move specific rows from an original table to a new table?

In SAS, I have a table that have 1000 rows. I am trying to separate that table into two tables. Row1-500 to Table A and row501-100 to table B. What is the code that can do this function. Thank you all for helping!
I am searching the code online and cannot get anything on google, help is appreciated.
The DATA statement lists the output tables of the step. An OUTPUT statement explicitly sends a row to each of the output tables. An explicit OUTPUT <target> ... <target-k> statement sends records to the specified tables only. The automatic implicit loop index variable _n_ can act as a row counter when a single data set is being read with SET.
Try
data want1 want2;
set have;
if _n_ <= 500 then output want1; else output want2;
run;
However, you may be better served by creating a categorical variable that can be used later in WHERE or BY statements.
Maybe the set options will help.Try firstobs= and obs= to choose the rows you want.
Here is how to use them:
data want1;
set have(obs=500);
run;
data want2;
set have(firstobs=501 obs=1000);
run;

SAS Proc format cntlin equivalent in Teradata

Is there an equivalent to the SAS format cntlin procedure in Teradata. I have a reference value table (code_value), which is used a lot and rather than doing many outer joins to the reference value table, I'd like to have a lookup function similar to the solution below in SAS. Any help is greatly appreciated.
data CodeValueFormat;
set grp.code_value (keep=code_value_id description);
fmtname = 'fmtCodeValue';
start = code_value_id;
label = description;
run;
proc format cntlin=work.codevalueformat;
run;
proc sql;
select foo_code_id format=fmtCodeValue.
from bar;
quit;
There is no way you can emulate SAS format cntlin procedure in Teradata or any other database other than using lookup tables. One way to avoid doing same joins again and again is to do index join. please look into below link to see whether this is what you want to do. https://info.teradata.com/HTMLPubs/DB_TTU_16_00/index.html#page/Database_Management%2FB035-1094-160K%2Fqiq1472240587768.html%23wwID0EFK1R
One another way is to maintain a denormalized table and do joins with your incremental/daily records in your staging area and then append this records to your final table

Export/Import Attributes of a SAS dataset

I am working with multiple waves of survey data. I have finished defining formats and labels for the first wave of data.
The second wave of data will be different, but the codes, labels, formats, and variable names will all be the same. I do not want to define all these attributes again...it seems like there should be a way to export the PROC CONTENTS information for one dataset and import it into another dataset. Is there a way to do this?
The closest thing I've found is PROC CPORT but I am totally confused by it and cannot get it to run.
(Just to be clear I'll ask the question another way as well...)
When you run PROC CONTENTS, SAS tells you what format, labels, etc. it is using for each variable in the dataset.
I have a second dataset with the exact same variable names. I would like to use the variable attributes from the first dataset on the variables in the second dataset. Is there any way to do this?
Thanks!
So you have a MODEL dataset and a HAVE dataset, both with data in them. You want to create WANT dataset which has data from HAVE, with attributes of MODEL (formats, labels, and variable lengths). You can do this like:
data WANT ;
if 0 then set MODEL ;
set HAVE ;
run ;
This works because when the DATA step compiles, SAS builds the Program Data Vector (PDV) which defines variable attributes. Even though the SET MODEL never executes (because 0 is not true), all of the variables in MODEL are created in the PDV when the step compiles.
Importantly, note that if there are corresponding variables with different lengths, the length from MODEL will determine the length of the variable in WANT. So if HAVE has a variable that is longer than the same-named variable in MODEL, it may be truncated. Options VARLENCHK determines whether or not SAS throws a warning/error if this happens.
That assumes there are no formats/labels on the HAVE dataset. If there is a variable in HAVE that has a format/label, and the corresponding variable in MODEL does not have a format/label, the format/label from HAVE will be applied to WANT.
Sample code below.
data model;
set sashelp.class;
length FavoriteColor $3;
FavoriteColor="Red";
dob=today();
label
dob='BirthDate'
;
format
dob mmddyy10.
;
run;
data have;
set sashelp.class;
length FavoriteColor $10;
dob=today()-1;
FavoriteColor="Orange";
label
Name="HaveLabel"
dob="HaveLabel"
;
format
Name $1.
dob comma.
;
run;
options varlenchk=warn;
data want;
if 0 then set model;
set have;
run;
I'd create an empty dataset based on the existing one, and then use proc append to append the contents to it.
Create some sample data for the second round of data:
data new_data;
age = 10;
run;
Create an empty dataset based on the original data:
proc sql noprint;
create table want like sashelp.class;
quit;
Append the data into the empty dataset, retaining the details from the original:
proc append base=want data=new_data force nowarn;
run;
Note that I've used the force and nowarn options on proc append. This will ensure the data is appended even if differences are found between the two datasets being used. This is expected if you have, for example, format differences. It will also hide things like if columns exist in the new table that aren't in the old table etc. So be careful that this is doing what you want it to. If the behaviour is undesirable, consider using a datastep to append instead (and list the want dataset first).
Welcome to the stack.
If you want to copy the properties of the table without the data within it, you could use PROC SQL or data step with zero rows read in.
This examples copies all information about the SASHELP.CLASS dataset into a brand new dataset. All formats, attributes, labels, the whole thing is copies over. If you want to only copy some of the columns, specify them in select clause instead of asterix.
PROC SQL outobs=0;
CREATE TABLE WANT as SELECT * FROM SASHELP.CLASS;
QUIT;
Regards,
Vasilij

proc contents out size sas

I am trying to create a meta data table for all the tables in the "xyzfolder" using the proc contents function (see below for more details). When the table "all" is created, I noticed that the "file size" column is missing. As in for table ABC in xyzfolder, I would like to look at a column "file size" to see if table ABC is greater than 1 GB.
proc contents data=xyzfolder._all_ out =work.all;
run;
Best way to do this is to use the dictionary tables. You can do that in SQL like so, or in regular SAS using sashelp.vtable.
proc sql;
create table all as
select * from dictionary.tables
where libname='SASHELP';
quit;
If filesize is known to SAS it will be listed here in the column filesize. If it's not known to SAS, you will need to provide some more information as to your operating system, the location and type of the libname, etc. to get useful responses.

Rename Variable Name Starting with Number in SAS

I have some results that came from a relational database in a SAS data set. All of the variable names start with numbers, so I can't rename them or access them in a data step. Is there any way to rename them or access them without getting the data out of the RDBMS again?
options validvarname=any; will allow you to access them, and perhaps even use the dataset - you can enclose an "illegal" variable name in "variable name"n (quotes then an n afterwards) to make a name literal which is equivalent to a variable name (like in Oracle using "variable name").
If you want to make them easier to use, you can do something like
proc sql;
select catx(' ','rename',name,'=',cats('_',name,';')) into :renamelist separated by ' '
from dictionary.columns
where libname='WORK' and memname='DATASETNAME'; *perhaps AND ANYDIGIT(substr(name,1,1)) as well;
quit;
proc datasets lib=work;
modify datasetname;
&renamelist;
quit;
You could also try setting options validvarname=v7; before you connect to the RDBMS as it's possible SAS will do this for you (depending on the situation) if you have it set that way (and don't currently).
The answer given by Joe has some helpful information, but I actually discovered that SAS has a (somewhat automatic) method for handling this. When you query data from an RDBMS, SAS will actually replace any column names starting with numbers with an underscore for the first character. So 1994Q4 becomes _994Q4. Thus, you can simply access the data that way.
SAS will, however, preserve the original name from the RDBMS as the variable title, so it will display as 1994Q4 (or whatever) in table view mode.