Multiple Conditions/variables in an IF-THEN statement SAS - if-statement

I have a data set which has two variables I'm trying to create new groups from. The first variable is "religiosity" and the second is "Av_Anti", both are numeric variables. I'm trying to create groups to separate into 9 groups, with low/mid/high religiosity AND low/mid/high Av_Anti.
DATA LYING1;
SET LYING;
IF RELIGIOSITY = (1 OR 2) AND Av_anti <=3 THEN Rel_Anti = "LowR,LowA";
IF RELIGIOSITY = (1 OR 2) AND Av_anti (>3 AND <=7) THEN Rel_Anti = "LowR,MidA";
IF RELIGIOSITY = (1 OR 2) AND Av_anti >7 THEN Rel_Anti = "LowR,HighA";
IF RELIGIOSITY = (3 OR 4 OR 5) AND Av_anti <=3 THEN Rel_Anti = "MidR,LowA";
IF RELIGIOSITY = (3 OR 4 OR 5) AND Av_anti (>3 AND <=7) THEN Rel_Anti = "MidR,MidA";
IF RELIGIOSITY = (3 OR 4 OR 5) AND Av_anti >7 THEN Rel_Anti = "MidR,HighA";
IF RELIGIOSITY = (6 OR 7) AND Av_anti <=3 THEN Rel_Anti = "HighR,LowA";
IF RELIGIOSITY = (6 OR 7) AND Av_anti (>3 AND <=7) THEN Rel_Anti = "HighR,MidA";
IF RELIGIOSITY = (6 OR 7) AND Av_anti >7 THEN Rel_Anti = "HighR,HighA";
ELSE Rel_Anti = "Error";
RUN;
I keep getting the message
"The function AV_ANTI is unknown, or cannot be accessed."
The thing is, I've checked that variable, its spelled correctly and its listed in the called dataset. I don't know why SAS wouldn't be recognizing it as a variable? I also seem to be getting some issues with the logical operators (the >, <=). Am I missing something?

You have invalid SAS Syntax in your comparisons/ranges.
You should use the IN operator to check for inclusion in a list of values and then compare each variable to boundaries for each comparison. (i.e. not
Not:
Av_anti (>3 AND <=7)
But:
Av_anti>3 and Av_anti<=7
or :
3<AV_atni<=7
The following should work. I also think you intend to have else if rather than all if's throughout, otherwise your last condition will set all to Error or LowR/MidA.
DATA LYING1;
SET LYING;
IF RELIGIOSITY in (1, 2) AND Av_anti <=3 THEN Rel_Anti = "LowR,LowA";
ELSE IF RELIGIOSITY in (1, 2) AND (Av_anti >3 AND AV_anti<=7) THEN Rel_Anti = "LowR,MidA";
...
ELSE Rel_Anti = "Error";
RUN;
A better solution might be:
Data lying1;
set lying;
IF RELIGIOSITY in (1, 2) then P1='LowR';
else IF RELIGIOSITY in (3, 4, 5) then P1='MidR';
else IF RELIGIOSITY in (6,7) then P1='HighR';
else P1='Error';
if av_anti<=3 then P2='LowA';
else if 3<av_anti<=7 then P2='MidA';
else if AV_Anti>7 then 'HighA';
else P2='Error';
Rel_Anti=catx(",", P1, P2);
run;

Related

How do I turn a sequence of sequences into a map, where the values are the count of the first item in the sequence?

I have data like (("generic" 7) ("ore" 1) ("generic" 4) ("wood" 6) ("wheat" 3) ("generic" 2) ("generic" 9) ("sheep" 5) ("brick" 8))
and I want to turn it into
{"brick" 1
"generic" 4
"sheep" 1
"ore" 1
"wheat" 1
"wood" 1}
Since "generic" appears 4 times in the data, I want the key to be "generic" and the value to be 4. Since "sheep" appears 1 time in the data, I want the key to be "sheep" and the value to be "1".
Use map, first and frequencies:
(->> '(("generic" 7) ("ore" 1) ("generic" 4) ("wood" 6) ("wheat" 3) ("generic" 2) ("generic" 9) ("sheep" 5) ("brick" 8))
(map first)
frequencies)
=> {"generic" 4, "ore" 1, "wood" 1, "wheat" 1, "sheep" 1, "brick" 1}
(->> is "thread-last" macro.)

How do I find the maximum element from a list in CLIPS?

I am trying to find out the maximum element from a list, e.g.
(deffacts list
(list 1 2 3 4 5 6 7 6 5 4 3 2 1))
in CLIPS. How can I do that, in a very simple way, in a defrule?
Also, if I have a template for a patient, with the following slots :
(deftemplate patient
(slot name)
(slot age)
(multislot tens_max)
(multislot tens_min))
(deffacts data_patient
(patient (name John) (age 22) (tens_max 13 15 22 11) (tens_min 6 7 14 6))
)
and I want to find out the maximum element from the last multislot, tens_min, how can I do that?
I would appreciate any suggestion.
You can use the max function to find the maximum value of its arguments. You can bind the list of numbers to a multifield variable in the conditions of a rule. The max function however expects separate arguments so you can't just pass it a multifield value. You can use the expand$ function to split a multifield value into separate arguments for a function call. The max function expects at least 2 arguments in CLIPS 6.3 and at least 1 in CLIPS 6.4, so for completeness you would need to handle these cases. You can create a deffunction to handle these edge cases in your code.
CLIPS (6.31 6/12/19)
CLIPS>
(deffunction my-max ($?values)
(switch (length$ ?values)
(case 0 then (return))
(case 1 then (return (nth$ 1 ?values)))
(default (return (max (expand$ ?values))))))
CLIPS>
(deffacts list
(list 1 2 3 4 5 6 7 6 5 4 3 2 1))
CLIPS>
(defrule list-max
(list $?values)
=>
(printout t "list max = " (my-max ?values) crlf))
CLIPS>
(deftemplate patient
(slot name)
(slot age)
(multislot tens_max)
(multislot tens_min))
CLIPS>
(deffacts data_patient
(patient (name John) (age 22) (tens_max 13 15 22 11) (tens_min 6 7 14 6)))
CLIPS>
(defrule patient-max
(patient (tens_min $?values))
=>
(printout t "patient max = " (my-max ?values) crlf))
CLIPS> (reset)
CLIPS> (run)
patient max = 14
list max = 7
CLIPS>

If Else Statement is giving an error that I'm missing an End If statement

I'm hoping for another set of eyes to look over my code. I'm writing a relatively big If...Else... statement. It appears that everything is coded properly. I've stepped through the entire script but one spot keeps giving me an "Expected 'End If'" When it seems to me that I don't need that.
Simply put, I'm trying to say: If blah, do these for things. Else If blah, only do one of those things.
Here's the block of code:
If(sLogFile <> "" AND nPing <> 1) Then
pingStatus = 1
If(findTag(sLogFile, daRunning) = 1) Then
daStatus = 1
Else If(findTag(sLogFile, daNotRunning) = 1) Then
daStatus = 2
Else
daStatus = 3
End If
If(daStatus = 1 AND findTag(sLogFile, daDataFlowing) = 1) Then
daFlowStatus = 1
Else If(daStatus = 1 AND findTag(sLogFile, daDataNotFlowing) = 1) Then
daFlowStatus = 2
Else If(daStatus = 1 AND findTag(sLogFile, daDataUnchecked) = 1) Then
daFlowStatus = 3
Else If(daStatus <> 1) Then
daFlowStatus = 4
End If
If(findTag(sLogFile, aeRunning) = 1) Then
aeStatus = 1
Else If(findTag(sLogFile, aeNotRunning) = 1) Then
aeStatus = 2
Else
aeStatus = 3
End If
If(findTag(sLogFile, aeDataUnchecked) = 1) Then
aeFlowStatus = 2
Else If(findTag(sLogFile, aeDataExecutionError) = 1) Then
aeFlowStatus = 3
Else If(findTag(sLogFile, aeDataConnectionError) = 1) Then
aeFlowStatus = 4
Else If(findTag(sLogFile, aeTimeStamp) = 1) Then
location = InStr(sLogFile, aeTimeStamp)
leftTrimmedString = LTrim(Mid(sLogFile, (location - 2)))
location = InstrRev(leftTrimmedString, ":")
dateString = Trim(Mid(leftTrimmedString, 1, (location + 5)))
timeDiff = DateDiff("h", dateString, Now)
If(timeDiff > 5) Then
aeFlowStatus = 5
Else
aeFlowStatus = 1
End If
End If
Else If(nPing = 1) Then
pingStatus = 2
If(findTag(sLogFile, aeDataUnchecked) = 1) Then
aeFlowStatus = 2
Else If(findTag(sLogFile, aeDataExecutionError) = 1) Then
aeFlowStatus = 3
Else If(findTag(sLogFile, aeDataConnectionError) = 1) Then
aeFlowStatus = 4
Else If(findTag(sLogFile, aeTimeStamp) = 1) Then
location = InStr(sLogFile, aeTimeStamp)
leftTrimmedString = LTrim(Mid(sLogFile, (location - 2)))
location = InstrRev(leftTrimmedString, ":")
dateString = Trim(Mid(leftTrimmedString, 1, (location + 5)))
timeDiff = DateDiff("h", dateString, Now)
If(timeDiff > 5) Then
aeFlowStatus = 5
Else
aeFlowStatus = 1
End If
End If
End If
The error keeps happening at the main Else If about 2/3 of the way down (Else If(nPing = 1) Then). I'm getting the error on that line.
I've tried separating the block into two blocks by putting an End If above the Else IF, then changing the Else If to an If. It works when I do that but I don't really want two if statements.
So, did I mess up, or is there a problem with my interpreter?
In Visual Basic the "else if" statement is written ElseIf not Else If. I think that's your problem.
The reason is that you should be using ElseIf not Else If. See the difference?
Now, the bigger issue is that you will always have trouble figuring out errors with such a huge chunk of "spaghetti code". Consider breaking your code up into small re-usable methods. That way, you'll be able to figure out where the problem lies more-easily. Not to mention the fact that it hurts to even look at all those if blocks all crammed together.

Matching two lists in excel

I am trying to compare two months sales to each other in excel in the most automated way possible (just so it will be quicker for future months)
This months values are all worked out through formulae and last months will be copy and pasted into D:E. However as you can see there are some customers that made purchases last month and then did not this month (and vice versa). I basically need to be have all CustomerID's matching row by row. So for example it to end up like this:
Can anyone think of a good way of doing this without having to do it all manually? Thanks
Use the SUMIFS function or VLOOKUP. Like this:
http://screencast.com/t/VTBZrfHjo8tk
You should just have your entire customer list on one sheet and then add up the values associated with them month over month. The design you are describing is going to be a nightmare to maintain over time and serves no purpose. I can understand you would like to see the customers in a row like that, which is why I suggest SUMIFS.
This option compare only two columns, I think you do to think anoter way,
first I will add the date/month and then you can add down the next month value:
then you can use a simply pivot to see more month in the some time
any case if you want to format your two columns, you can use this code (you will to update with you reference, I used the date from your img example)
Sub OrderMachColumns()
Dim lastRow As Integer
Dim sortarray(1 To 2, 1 To 2) As String
Dim x As Long, y As Long
Dim TempTxt10 As String
Dim TempTxt11 As String
Dim TempTxt20 As String
Dim TempTxt22 As String
lastRow = Range("A3").End(xlDown).Row ' I use column A, same your example
For x = 3 To lastRow * 2
Cells(x, 1).Select
If Cells(x, 1) = "" Then GoTo B
If Cells(x, 4) = "" Then GoTo A
If Cells(x, 1) = Cells(x, 4) Then
Else
If Cells(x, 1).Value = Cells(x - 1, 4).Value Then
Range(Cells(x - 1, 4), Cells(x - 1, 5)).Select
Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
ElseIf Cells(x, 1).Value = Cells(x + 1, 4).Value Then
Range(Cells(x, 1), Cells(x, 2)).Select
Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
Else
sortarray(1, 1) = Cells(x, 1).Value
sortarray(1, 2) = "Cells(" & x & ", 1)"
sortarray(2, 1) = Cells(x, 4).Value
sortarray(2, 2) = "Cells(" & x & ", 4)"
For Z = LBound(sortarray) To UBound(sortarray)
For y = Z To UBound(sortarray)
If UCase(sortarray(y, 1)) > UCase(sortarray(Z, 1)) Then
TempTxt11 = sortarray(Z, 1)
TempTxt12 = sortarray(Z, 2)
TempTxt21 = sortarray(y, 1)
TempTxt22 = sortarray(y, 2)
sortarray(Z, 1) = TempTxt21
sortarray(y, 1) = TempTxt11
sortarray(Z, 2) = TempTxt22
sortarray(y, 2) = TempTxt12
End If
Next y
Next Z
Select Case sortarray(1, 2)
Case "Cells(" & x & ", 1)"
Range(Cells(x, 1), Cells(x, 2)).Select
Case "Cells(" & x & ", 4)"
Range(Cells(x, 4), Cells(x, 5)).Select
End Select
Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
End If
End If
A:
Next x
B:
End Sub

Comparing tuples from two files in Pig

I want to compare tuples from two different files using Pig. If tuples are mirror image of each other, I want that tuple into file-f3.
If f1 has the following tuples
(1 2)
(3 4)
and f2 has following tuples
(5 6)
(4 3)
Since (3 4) is a mirror image of (4 3), we need to store this value in f3. Thus, f3 would be
(3 4)
You can simply inner join the 2 data sets like below:
data1 = LOAD '$data1' USING AvroStorage();
data2 = LOAD '$data2' USING AvroStorage();
output = JOIN data1 BY ($0, $1), data2 BY ($1, $0);
output2 = FOREACH output GENERATE data1.$0, data1.$1;