Sunday, October 17, 2010

The Serial Comma

This morning I was wandering through Wikipedia when I stumbled on "The Oxford Comma". I looked it up, and realized I had read about it before - the serial comma: the final comma that is followed by an and or an or, which is controversial in whether it should be used. In reading the arguments for and against, I realized that one argument for the usage was left out, and that much of the ambiguity in using it or not using it seem to be related to inconsistent noun usage. Let me explain.

The argument for the serial comma that I would like to add is for those people who convert our human languages into computer languages. It is much clearer what is desired of a computer when all commas are specified, for example: XYQ report needs names, jobs and titles. Does that mean two distinct fields: name and job/title; or three distinct fields: name, job, and title. Clarification is necessary, and at that point the original communication regarding the need would have been less useful.

One of the examples of ambiguity on the Wikipedia article was the following: They went to Oregon with Betty, a maid, and a cook. To a programmer, this statement mixes different fields up. The origin of the issue is not using a serial comma, but mixing Names with Jobs. In a database, there would two fields: Names and Jobs. No one would set up a database mixing the two because it would cause much confusion and conflict (e.g., if you find someone's name but the field is already occupied by their title, where do you put the name?), and language should follow the clarity of such a database structure.

That is to say that the original statement should use all names, all jobs, or both. For example: They went to Oregon with Betty, a nurse; Jenny, a maid; and Jim, a cook. Or: They went to Oregon with Betty, a maid, and Jim, a cook. Or: They went to Oregon with Betty, who is both the maid and cook. These statements are clearly about three people, two people, and one person, respectively. The original statement was confusing because of the mix of descriptions: Names and Jobs.

Back to the first part: In actual code, it is necessary to separate items in a list with commas every time. (Of course, there usually isn't an and separating items...) I wrote a query in SAS using spaces to separate items and then passed it to Oracle, but Oracle generated an error. Oracle required the commas, whereas SAS implies the separation of items by spaces alone. For example: I need the names of people who do the following jobs: journalist, lawyer, and accountant; so I would write the following criteria (let's ignore the possible issue of case-sensitivity):

where job in ('Journalist', 'Lawyer', 'Accountant')

Each item requires the comma separator. Now had the report required the names of people who eat eggs, toast and jam, I would be confused. Would that be 'eggs', 'toast and jam' or 'eggs', 'toast', 'jam'? A better way to say it, whichever way was meant would be: eggs, toast, and jam; or eggs, and toast with jam. I would have to figure out whether the database recorded 'toast with jam' or 'toast and jam' or some other variant ('jammed toast'?), but either revision would be much clearer.

In the end, if the serial comma creates confusion, revise the statement altogether; otherwise, use the serial comma!

Saturday, September 25, 2010

Thursday, August 12, 2010

CheckLog: A Utility for Reviewing the SAS Log

At my previous job, I worked on a SAS program that was intended to be run by someone who did not know SAS. So I needed a utility to tell the user whether the program completed successfully. The final result was a macro called CheckLog that checks a specified log, directory of logs, or the current log for error, warning, invalid, and other messages related to issues in a SAS program.

In order to accomplish this, I first needed a way to export the SAS log to a file so I could read it back in as a SAS data set and search for the terms and phrases associated with issues in the SAS program. Fortunately, there was already a utility available at work that exported the log to a file. The statement that exports the file is a simple DM statement, for example:

dm log "file 'C:\Directory\File.log' replace;" wpgm;

The next step required reading in the log into a data set. Initially, I used the import procedure (i.e., proc import) to import the text file into SAS. However, I needed to specify a delimiter that would not actually delimit the file. I wanted the file to be one large column. So I looked through the SAS font and found a character not common in English, the cedilla ( ¸ ). This character is also not usually found alone, even in languages that use it (like French). At least, I hope it isn't!

The last part is a continuing effort - identify and search for words and phrases associated with issues. The keywords were easy: error, warning, invalid, and uninitialized. The phrases, however, are elusive and open to interpretation. Sometimes phrases like "the data set has 0 observations" may be intended, and therefore should not be searched for. On the other hand, after completing an import, a data set with 0 observations is probably not intended. This type of issue requires the programmer to identify the problem.

Otherwise, the CheckLog macro can identify many common issues of varying levels of importance. Issues like the statement "numeric values have been converted to character values" or the statement "the query requires remerging summary statistics back with the original data" should be identified and resolved to avoid unintended consequences.

The macro includes several options. First, the macro can review a specified log, a directory of logs, or the current SAS log. As long as the file ends with ".log", it can be reviewed with this macro. Second, To enhance reviewing non-SAS logs, I added an argument to add additional keywords, like the word "caution" or "alert". Users could implement user-specified issues (instead of using put statements with the word ERROR or WARNING).

Third, the output can be renamed, with a default of "Log_issues". (When reviewing multiple logs from a directory, this option does not take effect, and the output is named "Logs_w_issues".) Fourth, an option to change the behavior of the pop-up message: always, never, and only when issues are found. Finally, an option to abort the currently executing SAS program if an issue is discovered. This allows the user to run code in production and end it prematurely if issues arise, so the code does not continue to execute with issues.

Readers interested in the macro can join a user group (see below) hosted by Google Groups to download the macro, view documentation, and receive emails when I updated the code. And please, send feedback! I would like to know if the macro works well and whether it checks for all of the issues users require.



CheckLog Site

CheckLog User Group

Description:

This group is a forum for the users of the SAS CheckLog macro to receive updates, ask questions, and post feedback. The CheckLog macro checks the SAS log(s) for issues, including lines with error, warning, invalid, or uninitialized messages. Additionally, other phrases associated with issues are checked, and specific phrases are ignored. The macro can also be used with non-SAS logs, as long as the log uses the same issue keywords.

Subscribe by Email:

Saturday, July 3, 2010

New Transitions

I have been working with an insurance company for almost two years, and I primarily worked with insurance claims to evaluate the effectiveness of care for our members and to discover patterns in care. Last week I accepted a new position with a physician clinical practice organization. The new position will provide experience on the other side of the health care industry, working with data from the doctor's office rather than the insurance company.

My wife, Kyra, is also looking for a new job. She's been having a rough time at her current child care center with the way it's being run. Last weekend she started submitting applications, and she's already had two interviews. She hopes to have a new job very soon, we hope with a daycare center where Luca can enroll and Kyra can seek state teaching certification. One day she would like to teach in an elementary school.

My son, Luca, has been growing rapidly. He's very talkative and he really seems to know what he wants. He enjoys going to school and visiting his friends. On the weekends, he's been taking swimming lessons and he loves the water! A bit too much actually--he really wants to swim on his own, but I'm sure he'd sink like a rock! Soon he will be two, and we hope to have a big birthday party for him.

So we're all undergoing changes. It may be a turbulent summer, but I hope we all end up a little older, a little wiser, and a little happier with these new transitions.

Friday, May 7, 2010

Open Last Table in SAS

I've been trying to find a way to open the last table created in SAS by using a keyboard shortcut. It's taken a while and many online searches to find it, but I finally figured out a good way to do it. I created a macro and set the macro to a keyboard shortcut. Here's the entire macro:

%macro OpenTable(table=&syslast) / des="Open a table";

dm "vt %sysfunc(compress(&table))" vt;

%mend OpenTable;

Set the macro to a keyboard shortcut by typing the following code into the keyboard shortcut editor window (F9):

gsubmit '%opentable;'

By default, the macro opens the last table created, and the argument can be modified for any table.

I'm so glad I found a way to do this! This should save a lot of time!

Update:

I added more to the macro code in case the table doesn't exist. Here's the new code:

%macro OpenTable(table=&syslast) / des="Open a table";

/* Check if table exists */
%if %sysfunc(exist(&table))=1 %then %do;

dm "vt %sysfunc(compress(&table))" vt;

%end;

/* Otherwise pop-up a message that it does not exist. */
%else %do;

dm 'postmessage "The specified table does not exist."';

%end;

%mend OpenTable;

Update Update:

I've developed a rather complex macro now that does the same thing:

OpenTable.sas