Write SAS Data-Labels to Excel file - sas

I try to write the labels of each variable to an Excelsheet in SAS. Im using the option DBLABEL=YESwhich allows you to print the labels as column headings in Excel. Unfortunately it seems that my Labels are too long. Does anybody has a solution? Here is the code I m using:
data test;
length a 3.
b 3.
c 3.;
input a b c;
label a = "this label is too long for writing it from sas to excel";
datalines;
18 20 15
25 20 80
63 72 14
run;
libname xls oledb provider="Microsoft.ACE.OLEDB.12.0"
preserve_tab_names=yes preserve_col_names=yes
datasource="f:my workspace\test_9.xls" provider_string="Excel 12.0";
data xls.test (dblabel=yes);
set test;
run;
libname xls clear;
This is ther error I receive.
ERROR: Error binding parameters: Invalid column name: this label is
too long for writing it from sas to excel
Thanks in advance

This doesn't appear to be a problem with proc export instead.
proc export data=test outfile="C:\test.csv" label;
run;

Related

How to use filters when importing on sas

I have a very large data table on "dsv" format and i'm trying to import it on sas. However i don't have enough space to import the full table and then filter it (i've done this for smaller tables).
Is there any way to filter the data while importing it because at the end i will only use a part of that table ? If i want for example to import only rows that have the value 103 for Var2
PS: i'm using "proc import" not "data - infile..." because i don't know the exact number of columns
Var1
Var2
Var3
A10
103
Test
A02
102
Hiis
...
...
....
Thank you
You can add dataset options to the dataset listed in the OUT= option of PROC IMPORT.
Example:
filename dsv temp;
data _null_;
input (var1-var3) (:$20.);
file dsv dsd dlm='|';
put var1-var3;
cards;
Var1 Var2 Var3
A10 103 Test
A02 102 Hiis
;
proc import file=dsv dbms=csv out=want(where=(var2=102)) replace ;
delimter='|';
run;
The result is a dataset with just one observation.
NOTE: The data set WORK.WANT has 1 observations and 3 variables.
If you don't know the name of the second variable you could always just read the header row first and put the name into a macro variable.
data _null_;
infile dsv dsd dlm='|' truncover obs=1;
input (2*name) (:$32.);
call symputx('var2',nliteral(name));
run;
proc import file=dsv dbms=csv out=want(where=(&var2=102)) replace ;
delimter='|';
run;
You can add a where dataset option to the out= statement. For example:
proc import
file = 'myfile.txt'
out = want(where=(var2=103))
...;
run;

Convert 500000 seconds to HH:MM:SS

I'm attempting to convert a bunch of columns which contain seconds to HH:MM:SS. Most entries are within a 24 hour period such as 78000 seconds.
For these I have used format time10. Which gives 21 hours and 42 minutes in this case.
However when I have something like 528846 seconds, sas returns its fine when I open the data set, however when I proc export:
Proc export data = myset
Outfile =mylocation\about.xlsx
Dbms=excel2000 replace;
Sheet="mysheet";
Run;
When I open the excel output my value shows as 00/01/1900 02:54:06. I've tried use the date formats in excel but cant get it do display as the 146:54:06 (528846 seconds to hours, mins and secs)
Any suggestions pls?
Do you really need the value as a number in EXCEL? If not then convert it to a string in that style in your SAS dataset before exporting it.
data for_export ;
set myset ;
time_string = put(time_var,time12.);
run;
proc export data=for_export file='mylocation\about.xlsx' dbms=xlsx replace;
sheet="mysheet";
run;
Excel will display hours > 24 if you use custom format [h]:mm:ss.
You can coerce output to use a custom format by using a Proc that allows ODS styling where in the style attribute setting tagattr="format:'[h]:mm:ss'" can be used.
Sample data (time10.)
data have;
format elapsed time10.;
input elapsed ##; datalines;
78000 86399 86400 86401 528846
;
Fix: Use ODS style attribute tagattr
ods excel file='try-2.xlsx';
proc print noobs label data=have;
var elapsed / style=[tagattr="format:'[h]:mm:ss'"];
run;
ods excel close;
Problem: Proc EXPORT
proc export data=have replace outfile='try-1.xlsx' dbms=xlsx;
sheet="My Sheet";
run;
options noxwait noxsync xmin;
%sysexec start "Preview" try-1.xlsx;
The EXPORT DBMS=XLSX engine outputs SAS time10. formatted data values as cells with Excel custom format h:mm. (Note: Output made with SAS 9.4 M6)

Produce custom table in SAS with a subsetted data set

I want to use SAS and eg. proc report to produce a custom table within my workflow.
Why: Prior, I used proc export (dbms=excel) and did some very basic stats by hand and copied pasted to an excel sheet to complete the report. Recently, I've started to use ODS excel to print all the relevant data to excel sheets but since ODS excel would always overwrite the whole excel workbook (and hence also the handcrafted stats) I now want to streamline the process.
The task itself is actually very straightforward. We have some information about IDs, age, and registration, so something like this:
data test;
input ID $ AGE CENTER $;
datalines;
111 23 A
. 27 B
311 40 C
131 18 A
. 64 A
;
run;
The goal is to produce a table report which should look like this structure-wise:
ID NO-ID Total
Count 3 2 5
Age (mean) 27 45.5 34.4
Count by Center:
A 2 1 3
B 0 1 1
A 1 0 1
It seems, proc report only takes variables as columns but not a subsetted data set (ID NE .; ID =''). Of course I could just produce three reports with three subsetted data sets and print them all separately but I hope there is a way to put this in one table.
Is proc report the right tool for this and if so how should I proceed? Or is it better to use proc tabulate or proc template or...?
I found a way to achieve an almost match to what I wanted. First if all, I had to introduce a new variable vID (valid ID, 0 not valid, 1 valid) in the data set, like so:
data test;
input ID $ AGE CENTER $;
if ID = '' then vID = 0;
else vID = 1;
datalines;
111 23 A
. 27 B
311 40 C
131 18 A
. 64 A
;
run;
After this I was able to use proc tabulate as suggested by #Reeza in the comments to build a table which pretty much resembles what I initially aimed for:
proc tabulate data = test;
class vID Center;
var age;
keylabel N = 'Count';
table N age*mean Center*N, vID ALL;
run;
Still, I wonder if there is a way without introducing the new variable at all and just use the SAS counters for missing and non-missing observations.
UPDATE:
#Reeza pointed out to use the proc format to assign a value to missing/non-missing ID data. In combination with the missing option (prints missing values) in proc tabulate this delivers the output without introducing a new variable:
proc format;
value $ id_fmt
' ' = 'No-ID'
other = 'ID'
;
run;
proc tabulate data = test missing;
format ID $id_fmt.;
class ID Center;
var age;
keylabel N = 'Count';
table N age*(mean median) Center*N, (ID=' ') ALL;
run;

Formats export with variable names in SAS

I created a format for a variable as follows
proc format;
value now 0=M
1=F
;
run;
and now I apply this to a dataset.
Data X;
set X2;
format Var1 now.;
run;
and I want to export this format using cntlout
proc format library=work cntlout=form; run;
this gives me the list of formats in the library catalog. But doesnot give me the variable name to which it is attached.
How can I create a dataset with list of formats and the attached variables to it?
So I can see which format is linked to what variable.
If you just want to look up the variables in a specific dataset, often PROC CONTENTS is faster than using SASHELP.VCOLUMN or DICTIONARY.TABLES, particularly when there are lots of libraries/datasets defined.
57 proc contents data=x out=myvars(keep=name format) noprint;
58 run;
NOTE: The data set WORK.MYVARS has 1 observations and 2 variables.
59
60 data _null_;
61 set myvars;
62 put _all_;
63 run;
NAME=Var1 FORMAT=NOW _ERROR_=0 _N_=1
NOTE: There were 1 observations read from the data set WORK.MYVARS.
Assuming you want this for a specific library you can use the SASHELP.VCOLUMN dataset. This dataset contains the formats for all variables and you can filter it as desired.

proc contents is truncating the values in out put dataset.How to get full values in out put dataset?

I'm trying to get all dataset names in a library in to a data set.
proc datasets library=LIB1 memtype=data ;
contents data=_all_ noprint out=Datasets_in_Lib1(keep=memname) ;
run;
The final data set (Datasets_in_Lib1) is having all the data set names that are in LIB1, but names are truncated to 6 characters.Is there any way to get full names of the datasets with out truncation.
Ex: If dataset name is x123456789, the Datasets_in_Lib1 will have x12345 only.
Thanks in advance,
Sam.
Agree with the comment, in 9.3 memname is $32. I don't think there was a version of SAS where data set names were limited to 6 characters. They went from 8 characters to 32 characters in v7 (I think).
Here's a log from running your code, showing it works as you want in 9.3
51 data work.x123456789;
52 x=1;
53 run;
NOTE: The data set WORK.X123456789 has 1 observations and 1 variables.
54
55 proc datasets library=work memtype=data nolist;
56 contents data=_all_ noprint out=Datasets_in_Lib1(keep=memname) ;
57 run;
NOTE: The data set WORK.DATASETS_IN_LIB1 has 1 observations and 1 variables.
58
59 data _null_;
60 set Datasets_in_Lib1;
61 put _all_;
62 run;
MEMNAME=X123456789 _ERROR_=0 _N_=1
NOTE: There were 1 observations read from the data set WORK.DATASETS_IN_LIB1.
You can also query the sashelp.vtable to obtain the list of datasets:
proc sql;
create table mem_list as
select memname
from sashelp.vtable
where libname='LIB1' and memtype='DATA';
quit;