BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
sam2
Calcite | Level 5

good morning, I am trying to create a cross tab table using proc tabulate, but am having a difficult time because one of my variables is a character. I am relatively new to using SAS and am unsure if there is a way to format the variable or transform the variable so it will fit in the body of my table. The data I am using looks somewhat like this:

 

data try;

input Market $ Number Type $;

datalines;

Eastern 17 Low

South 25 Mid

Midwest 92 High

West 33 Mid

;

run;

 

Market would be my class variable in proc tabulate and then I would like two columns, one with the number and one with the type. My tabulate statement looks like this:

 

proc tabulate data=try;

class Market;

var Number;

var Type;

table Market, Number='Count' Type;

run;

 

but when I run it, I get the inevitable error:

105

106 proc tabulate data=try;

107 class Market;

108 var Number;

109 var Type;

ERROR: Variable Type in list does not match type prescribed for this list.

110 table Market, Number='Count' Type;

111 run;

NOTE: The SAS System stopped processing this step because of errors.

NOTE: PROCEDURE TABULATE used (Total process time):

real time 0.00 seconds

cpu time 0.00 seconds

 

is there a way to get around this problem?

 

thank you for any assistance you can give.

 

1 ACCEPTED SOLUTION

Accepted Solutions
ballardw
Super User

Please post code using the ^^ Run icon above.

You had several Issues: First in your TRY2 dataset you did not create a numeric value. You generated warnings because you attempted to use numeric format and informat with a variable Try that was character. Here is how to create a numeric variable from

your existing type.

Second your Proc Tabulate should reference the new dataset, Try2. You were still pointing it to the original Try. Then you need to use the numeric version of the variable. Make sure to reference it in the VAR and Table statements with the same name.

data try2;
   set try;
   format typeNum type.;
   TypeNum = input(type,type.);
run;
/* two things: First you would need your Try2 set
and use the numeric version*/
proc tabulate data=try2;
class Market;
var Number;

var TypeNum;
table Market='', Number='Count'*sum='' TypeNum*max=''*f=type.;
run;

View solution in original post

16 REPLIES 16
howarder
Obsidian | Level 7

You need 'Type' in the class statement as well since it is a character variable.

howarder
Obsidian | Level 7

Also I believe that this code will help you get the result that you are trying to get..

 

proc tabulate data=try;
class Market Type;
var Number;
table Market*type,Number='Count';
run;
sam2
Calcite | Level 5

thank you for the assistance Howarder,

 

When I run it the way you suggest I get a cross tab table that looks like this;

 

Market    Type   

Eastern   Low   17

Midwest   High  92

etc.

 

is there a way to get the Type character variable to be placed in the body of the cross tab?

 

Market          Count           Type

Eastern         17                 Low

Midwest        92                 High

etc.

 

thank you again for all your help.

 

take care,

 

sam

 

Astounding
PROC Star

Here's a different structure that looks more like a cross-tab ... worth playing with if you like the idea:

 

proc tabulate data=try;

class Market Type;

var Number;

table Market, Type=' ' * Number=' ' * sum=' ';

run;

sam2
Calcite | Level 5

Thank you Astounding, I played with this a little and it still slightly misses what I am trying to get to.  I need for my table to have the market area as the row header and then in the body of the report, I get a Column specifically with the Count number in it and another column with the description of the market in it or Type. Is it possible to place character variables in a column instead of a numeric variable?  So the way I am looking for this to set up is:

 

Market      Count      Type

Eastern       17           Low

etc.

 

As always, I appreciate all the assistance.

 

sam

Astounding
PROC Star

How is this any different than using PROC PRINT? 

 

It is possible that PROC TABULATE is not the right tool for the job.

sam2
Calcite | Level 5

Oh it is very possible that proc tabulate isn't what I should be using.  I am simplifying the data, so a lot of other things are going on within the proc tabulate piece, but the sticking point I am having is putting the character variable into the body of the chart. Ultimately, the chart has 14 columns, there are calculations occurring, several subcategories, I feel like it would best be done with proc tabulate or proc report, but with either of them I can't seem to add the Character variables to the body.  Is there a way that you would know to get around this, or is there a better process to use given your limited knowledge of my data set.

 

Thank you,

 

sam

Astounding
PROC Star

Based on everything you have mentioned, taken as a whole, I think the approach should be:

 

  • Perform all the calculations (without generating a report), and save the results in a data set.
  • Use PROC PRINT on the calculated data set.

If I knew more details I might think about it differently, but there is no easy way for PROC TABULATE to print a character field as a column in the middle of the report.

ballardw
Super User

The only way to get text in the order you are indicating is to have the type value represented by a numeric value that can appear on the Var statement AND use a custom format with an appropriate statistic. If your "Type" is dependent on the Count variable this might be the best approach.

Please examine:

Proc format library=work;
invalue type
   'Low'  = 1
   'Mid'  = 2
   'High' = 3
;
value type
   1 = 'Low'
   2 = 'Mid'
   3 = 'High'
;
run;
data try;
   informat type type.;
   format   type type.;
input Market $ Number Type ;
datalines;
Eastern 17 Low
South 25 Mid
Midwest 92 High
West 33 Mid
;
run;
proc tabulate data=try;
   class Market;
   var Number;
   var Type;
table Market, Number='Count'*sum='' Type*max=''*f=type.;
run;

I read the data with a custom format, you could add a new variable such a TypeNum using

 

Typenum = input(Type,Type.);

and use that numeric variable with the format.

 

Caution: This may not work if crossing type with other statistics and if your Type changes within Market the result isn't reliable.

sam2
Calcite | Level 5

Thank you Ballardw, this is doing what I want it to do.  I apologize, but I am not strong on what you have done.  In my original dataset, I am reading in the data before I start proc tabulate, so the data is already read in, can you show me how I would do this if you read in this file first?

 

thanks for all the assistance,

 

sam

 

 

ballardw
Super User

Many users here don't want to download Excel files because of virus potential, others have such things blocked by security software. Also if you give us Excel we have to create a SAS data set and due to the non-existent constraints on Excel data cells the result we end up with may not have variables of the same type (numeric or character) and even values.

 

I usually turn Excel files into CSV and import according to rules about what data types and expected values in the data set.

 

If you already have a SAS data set then this link: https://communities.sas.com/t5/SAS-Communities-Library/How-to-create-a-data-step-version-of-your-dat... will show you how to create datastep text that can be posted here, either paste into the window or attach as a TXT file that we can then run and recreate your data. You only need to include enough data to recreate significant issues. Generally at least two values of any category and if missing values need special treatment then some of those.

howarder
Obsidian | Level 7

If you want the columns in a certian order, you may want to look into Proc Report to create your desired output.

sam2
Calcite | Level 5

I apologize Ballardw, that is a mistake I will not make again.  I was giving you a file that you could read in, the data is the same as what the datastep did before, but I think you will see what I am trying to do from this.  If the data is already read, can you format a particular column from that data that is a character into a numeric and allow me to put it in a proc tabulate column.

 

so, instead of formatting and then reading in the data, do it something like this:

 

data try;

input Market $ Number Type $;

datalines;

Eastern 17 Low

South 25 Mid

Midwest 92 High

West 33 Mid

;

run;

 

Proc format library=work;

invalue type

'Low' = 1

'Mid' = 2

'High' = 3

;

value type

1 = 'Low'

2 = 'Mid'

3 = 'High'

;

run;

data try2;

set try;

informat type type.;

format type type.;

run;

proc tabulate data=try;

class Market;

var Number;

var Type;

table Market='', Number='Count'*sum='' Type*max=''*f=type.;

run;

 

this does not run for me when I try it like this, I know it is in what I am doing, but can you provide assistance?

 

thank you again and have a great day!

 

sam

 

ballardw
Super User

Please post code using the ^^ Run icon above.

You had several Issues: First in your TRY2 dataset you did not create a numeric value. You generated warnings because you attempted to use numeric format and informat with a variable Try that was character. Here is how to create a numeric variable from

your existing type.

Second your Proc Tabulate should reference the new dataset, Try2. You were still pointing it to the original Try. Then you need to use the numeric version of the variable. Make sure to reference it in the VAR and Table statements with the same name.

data try2;
   set try;
   format typeNum type.;
   TypeNum = input(type,type.);
run;
/* two things: First you would need your Try2 set
and use the numeric version*/
proc tabulate data=try2;
class Market;
var Number;

var TypeNum;
table Market='', Number='Count'*sum='' TypeNum*max=''*f=type.;
run;

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 16 replies
  • 9638 views
  • 1 like
  • 5 in conversation