0

I have a data set with a variable named "Condition" that I want to use in the code. I'm guessing I need to do it in a macro but I'm still learning how to write macros in SAS.

So if my data set is this:

Question,Answer,Condition,Result
Q1,1,Answer=1," "
Q2,2,Answer=1," "
Q3,3,Answer=4," "

Then I want the program to take the Condition variable as a string and then use it as an if statement:

if Condition then Result = "Correct";

Is this possible?

Joe
  • 62,789
  • 6
  • 49
  • 67
Andy
  • 11
  • 3
  • 1
    Actually if you really have questions and answers and a set of valid answers then you might want to look into using PROC SCORE to "grade" the answers. – Tom Aug 24 '15 at 19:08
  • What I'm trying to accomplish is a program that checks a data set for skip-patterns and answers that depend on how other questions were answered. What I came up with is for the researcher to create an answer key using Excel (that they are familiar with) and a part of the key is adding the condition that must be true for the question to be answered. The researcher writes the condition ("Answer = 1") and then the program takes the actual answers and flags those that do not meet the condition. I'm hoping to not hard code the conditional statements but have the researcher write them into excel. – Andy Aug 24 '15 at 19:41
  • @Andy You might want to see my co-written paper from MWSUG2014, [Documentation Driven Programming](http://www.mwsug.org/proceedings/2014/BB/MWSUG-2014-BB11.pdf), which is pretty close to what you're doing. It shows a similar approach. – Joe Aug 24 '15 at 19:48
  • Can't you just create a new column from your condition column containing the correct answer to each question, then compare the given answer to the correct answer? Or am I missing something? – user667489 Aug 24 '15 at 19:49
  • @user667489 Given the clarifying comment, that sort of thing wouldn't work - the logic is more than simply "one correct answer" for skip pattern and range checks. – Joe Aug 24 '15 at 19:53
  • @Andy If your data's vertical like this, by the way, Tom's answer doesn't really work as well - because you're going to have to see the value for a previous variable for that respondent. You probably don't want to have the logic built in at a respondent level - the skip pattern is probably one set of logic you should apply for all users. If you want to ask about this in more detail, I'd ask a new question with your particulars (and an example dataset with a couple of respondents and several questions some of which depend on each other), and be more specific. – Joe Aug 24 '15 at 19:55
  • I was able to create a range check (those are different columns). I want the skip check to be more dynamic since some questions require this _or_ that, this _and_ that, this _not_ that...and so on. I'll take a look at the paper. – Andy Aug 24 '15 at 19:58
  • @Joe, that's a good idea. I'll read your paper and then re-post with more clarification and examples. I'm under a short deadline and was hoping there would be a simple solution using a macro but if not, I could create something more complex using more columns for each kind of condition and an "In" condition as a fall back for something more complicated. – Andy Aug 24 '15 at 20:03
  • I like the idea of a macro solution. %skipcheck(skiptrigger=/*condition that triggers skip*/, skipvars=/*list of vars to be skipped*/). If you have that, then you can use have users maintain a file that has one record per each skip pattern. And then use call execute or similar to invoke the macro as many times as needed. This would work better if your data are not as vertical as you suggest. But could work with that structure. – Quentin Aug 24 '15 at 22:15

1 Answers1

1

That is not easy to do. For your simple example you could do:

data want ;
   set have ;
   if cats('Answer=',answer) = condition then .... 

But that will not generalize to situations where CONDITION references the values of other variables. You might be able to generate code from a set of unique values of CONDITION.

Sample data:

data have ;
  infile cards dsd truncover ;
  input Question $ Answer Condition :$30. Expected $ ;
cards;
Q1,1,Answer=1,"Correct"
Q2,2,Answer=1,"Wrong"
Q3,3,Answer=4,"Wrong"
;;;;

Generate code using unique values of CONDITION.

filename code temp ;
data _null_;
  set have end=eof ;
  by condition ;
  file code ;
  if _n_=1 then put 'SELECT ;' ;
  if first.condition then put '  WHEN (' CONDITION= :$quote. ' AND (' condition ')) RESULT="CORRECT" ;' ;
  if eof then put '  OTHERWISE RESULT="WRONG";'
                / 'END;'
  ;
run;

Use the generated code in a data step.

data want ;
  set have ;
  %inc code / source2;
run;

Sample Log records.;

252  data want ;
253    set have ;
254    %inc code / source2;
255 +SELECT ;
256 +  WHEN (Condition="Answer=1"  AND (Answer=1 )) RESULT="CORRECT" ;
257 +  WHEN (Condition="Answer=4"  AND (Answer=4 )) RESULT="CORRECT" ;
258 +  OTHERWISE RESULT="WRONG";
259 +END;
NOTE: %INCLUDE (level 1) ending.
260  run;
Tom
  • 47,574
  • 2
  • 16
  • 29