BookmarkSubscribeRSS Feed
abbiedent95
Calcite | Level 5

Hi,

 

I am working with SAS 9.4.

 

I am trying to create an informat which converts numeric grades (0 through 100) to character grades (A, B, C, D, E, F). If the grade is already in character format, I want the informat to keep it the same but convert it to uppercase which is why I have included the UPCASE option. This does not always work.

 

When I try to create this informat and put in a range of 90-100, I get an error saying that the start is greater than the end. I tried to fix this error by putting in a range of 90-high instead. When I do this, I don't get the error but the numeric values of 100 are still not read correctly because they are output as the character value "F" instead of "A". On top of that, when I apply this informat SAS creates many extra observations with values of "F" that aren't supposed to be there.

 

Here is the code I created:

proc format;
invalue $Grades(upcase just)
		90 - 100 = 'A'
		80 - 89 = 'B'
		70 - 79 = 'C'
		60 - 69 = 'D'
		low - 59 = 'F'
		other = _same_ ;
run;

data GradesExample;
input Grade $Grades3. @@;
datalines;
100 56 a  79 94 84  C100
;
run;

I have also attached a screenshot of a report of GradesExample so that you can see the errors I'm talking about.informattrouble.PNG

 

3 REPLIES 3
PaigeMiller
Diamond | Level 26

 

 

 69         proc format;
 70         invalue $Grades(upcase just)
 71         90 - 100 = 'A'
 ERROR: Start is greater than end: -.
 72         80 - 89 = 'B'
 73         70 - 79 = 'C'
 74         60 - 69 = 'D'
 75         low - 59 = 'F'
 76         other = _same_ ;
 NOTE: The previous statement has been deleted.
 77         run;

 

So this particular informat isn't valid, and can't be used like this. Why isn't it valid, why does it say "start is greater than end"? 90 isn't greater than 100, is it? Yes it is, because character values sort alphabetically, 90 is greater than 100 because the first character of 90 which is 9 is greater than the first character of 100 which is 1.

 

If you create a numeric format, and read the data in as numeric, you get most of the way there. Numbers should be treated as numbers whenever you can.

 

proc format;
value Grades
		90 - 100 = 'A'
		80 - 89 = 'B'
		70 - 79 = 'C'
		60 - 69 = 'D'
		low - 59 = 'F';
run;

data GradesExample;
    input grade @@;
    format grade grades.;
datalines;
100 56 a  79 94 84  C100
;

 

It won't read grades that have character string in them, you can work around that as well if necessary.

--
Paige Miller
Quentin
Super User

You're creating a character informat. The docs state:

"The INVALUE, PICTURE, and VALUE statements accept numeric values on the left side of the equal sign. In character informats, numeric ranges are treated as character strings."

https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/proc/n03qskwoints2an1ispy57plwrn9.htm

 

So even though you've typed what looks like a number, it is treated in the informat as a character string.

 

If you know you always have character strings that represent integers in the range 0-100, you might be able to hack together something workable like:

 

proc format;
  invalue $Grades(upcase just)
    90 - 99,100 = 'A'
    80 - 89 = 'B'
    70 - 79 = 'C'
    60 - 69 = 'D'
    0,1,6,7,8,9,10,11 - 59 = 'F'   
    other = _same_ 
  ;
run;

data GradesExample;
input Grade : $Grades3. @@;
datalines;
100 56 a  79 94 84  C100 8
;
run;

But I think life will be easier if you just read the grades into a numeric variable, and use a format to group the numeric ranges into the letter grades.

 

The Boston Area SAS Users Group (BASUG) is hosting our in person SAS Blowout on Oct 18!
This full-day event in Cambridge, Mass features four presenters from SAS, presenting on a range of SAS 9 programming topics. Pre-registration by Oct 15 is required.
Full details and registration info at https://www.basug.org/events.
Tom
Super User Tom
Super User

Informats convert TEXT into VALUES.  So the ranges must be valid character ranges.  The range '90' to '100' is not valid since '9' comes before '1'.

 

Formats convert VALUES into TEXT.  So if you want to convert numbers into letters it would be easier to start with numbers.  You could use the MISSING statement to tell SAS to treat single letters A, B, C, D, F as indications of special missing values and then include them into your format defintion.

proc format;
value Grade
		90 - 100,.A = 'A'
		80 - 89,.B = 'B'
		70 - 79,.C = 'C'
		60 - 69,.D = 'D'
		low - 59,.F = 'F'
		other = 'U' 
;
run;

missing ABCDEF ;
data GradesExample;
  input Score @@;
  Grade = put(score,grade.);
datalines;
100 56 a  79 94 84  C 100
;

proc print;
run;
Obs    Score    Grade

 1      100       A
 2       56       F
 3        A       A
 4       79       C
 5       94       A
 6       84       B
 7        C       C
 8      100       A

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

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
  • 3 replies
  • 320 views
  • 2 likes
  • 4 in conversation