SAS PROC FORMAT - Define 'Other' Range for Numeric Variable - format

I've created a format that assigns a State label to a pre-defined range of Start-End numeric postcodes.
i.e.
Start | End | State
2600 | 2618 | ACT
2900 | 2949 | ACT
4000 | 4899 | QLD
I want to add a piece of code to the format file that assigns it a label "Error" when the postcode falls outside of my range.
In a previous thread, someone suggested using the HLO solution but I have tried implementing it with mixed success.
rsubmit;
data Fmt_State;
set State end=eof;
retain type 'n';
fmtname = 'category';
start = pcode_fr;
end = pcode_to;
label = State;
* For the first observation, assign the ‘LOW’ keyword;
if _n_ eq 1 then HLO='L';
if eof then do;
*** For the last observation, assign the ‘HIGH’ keyword and output;
HLO='H';
output;
*Define an 'Other' range that is outside the bounds of LOW and HIGH;
HLO='O';
label = "Error";
output;
end;
else output;
run;
endrsubmit;
Oddly, only the Middling ranges BETWEEN Low-High that are correctly labelled Error and the ranges outside Low-High that are incorrectly labelled. (I would expect the opposite to be true but still not working the way I want)
For clarity this is what's happening from my same ruleset:
Pcode | ShouldReturn (Reason) | ActuallyReturns
2615 | ACT | ACT
2000 | Error (TooLow) | ACT
2700 | Error (Undefined range) | Error
5000 | Error (Too High) | QLD
I just want anything undefined to be called Error despite it being too low or too high. Please help!

Your logic is incomplete. You want to add three new records.
START END HLO LABEL
. 2600 L Error (Too Low)
4899 . H Error (Too High)
- - O Error (Undefined range)
So you want logic like this:
if _n_=1 then do;
start=.;
end=from;
hlo='L';
label='Error (Too Low)';
output;
end;
start=from;
end=to;
label=state;
hlo=' ';
output;
if eof then do;
end=.;
start = to;
hlo='H';
label='Error (Too High)';
output;
hlo='O';
label='Error (Undefined Range)';
output;
end;

Related

how to get the complete source code location corresponding to the ASTnode in clang

i am using clang plugin to develop a tool which can insert a 'printf' statemente behind every statement to trace the project.for example:
int main(){
int a=1000;
if(a==1000){
a=999;}
}
insert a 'printf' statemente
int main(){
int a=1000;
printf("int a=1000;");
if(a==1000){
a=999;
printf("a=999;");}
}
i use the structure of the 'printFunctionName' in the clang'example to realize.
i need to get the complete source code location corresponding to the ASTnode so that i can insert the 'printf' statement in the right location.however i found i can't use the Stmt->getSourceRange() function to get the complete location range for some Specific type statement.for example,BinaryOperator,UnaryOperator.
a=1000;
| | | |-BinaryOperator 0x565356502960 <line:13:3, col:5> 'int' '='
| | | | |-DeclRefExpr 0x565356502918 <col:3> 'int' lvalue Var 0x565356502880 'a' 'int'
| | | | `-IntegerLiteral 0x565356502940 <col:5> 'int' 1000
In fact, these characters occupy 5 columns in the source code file, but only 3 columns are recognized.
a++;
-UnaryOperator 0x5653565029b0 <line:14:9, col:10> 'int' postfix '++'
| | | | `-DeclRefExpr 0x565356502988 <col:9> 'int' lvalue Var 0x565356502880 'a' 'int'
this is three chars for 3 column.but clang think it is 2 column.
do you have some idea to solve this problem?and coud you please give me some advices to better recognize the location for a complete sentence end with ';'?thank you!
and this is my code:
SourceRange range=declStmt->getSourceRange();
TheRewriter.ReplaceText(declStmt->getSourceRange(),str+";"+"\nprintf(\""+str+"\\n\")");

How to duplicate Sum(Sum(Fields!VarName.Value)) using Lookupsets and Custom Code in SSRS

I am fairly new to SSRS but am having a problem double summing when using Lookupsets as output. I have the following table and query which does work
Query for Hours_DataSet
SELECT CallbackDate, SUM(TelemarketingHours) AS DailyHours,
(SELECT SUM(TelemarketingHours) AS Expr1
FROM CallbackTbl) AS HoursPTD
FROM CallbackTbl AS CallbackTbl_1
GROUP BY CallbackDate
Definition of Matrix
| [CallbackDate] | Weekly totals
________________________________________________________________
Hours | [Sum(DailyHours]) | Sum(Sum(DailyHours))
The output is this:
12/01/2014 | 12/02/2014 | 12/03/2014 | 12/04/2014 | 12/05/2014| Weekly totals|
28.75 | 42 | 42.25 | 40.25 | 37.50 | 190.75
In another table I need to calculate the appointments per hour and total appointments per hour for the week. So I set the main data-set to be the number of appointments and use lookupset and custom code to do the summing.
Everything works well for one level of sum. I need to recreate the 190.75 number and use it in the as the denominator in the calculation for number of appointments per hour for the week.
Query for Positive_DataSet:
SELECT MainHistory_1.REALDATE, StatusTbl.Status, COUNT (MainHistory_1.DBRECID) AS Positives, StatusTbl.Code,
(SELECT COUNT(DBRECID) AS Expr1
FROM MainHistory
WHERE (REALDATE > CONVERT(DATETIME, #StartDate, 102)) AND (REALDATE < CONVERT(DATETIME, #EndDate, 102))) AS TotalCalls
FROM MainHistory AS MainHistory_1 INNER JOIN
StatusTbl ON MainHistory_1.STATUS = StatusTbl.Status
GROUP BY MainHistory_1.REALDATE, StatusTbl.Status, StatusTbl.Code
HAVING (StatusTbl.Code = 'P') AND (MainHistory_1.REALDATE > CONVERT(DATETIME, #StartDate, 102)) AND (MainHistory_1.REALDATE < CONVERT(DATETIME, #EndDate, 102))
My Matrix looks like this:
[REALDATE]| Weekly Totals
EXPR | EXPR
where the expressions are
FORMAT(Code.CalcPerHour(Lookupset(FORMAT(Fields!REALDATE.Value,"Long Date"),FORMAT(Fields!CallbackDate.Value,"Long Date"),Fields!DailyHours.Value,"Hours_DataSet"),SUM(Fields!Positives.Value)),"Fixed")
Sum(Sum(Fields!Positives.Value))/SUM(code.CalcPTD(Lookupset(FORMAT(Fields!REALDATE.Value,"Long Date"),FORMAT(Fields!CallbackDate.Value,"Long Date"),Fields!DailyHours.Value,"Hours_DataSet")))
My custom code is this:
PUBLIC SHARED FUNCTION CalcPerHour(Hours AS OBJECT, Totals AS OBJECT) AS DECIMAL
DIM i AS INTEGER
DIM PerHour AS DECIMAL
FOR i=0 TO UBOUND(Hours)
IF CINT(Hours(i)) < > 0 THEN
PerHour = PerHour + (CDEC(Totals)/CDEC(Hours(i)))
END IF
Next i
RETURN PerHour
END FUNCTION
PUBLIC SHARED FUNCTION CalcPTD(LookupArray AS Array) AS DECIMAL
DIM I AS INTEGER
DIM Total AS DECIMAL
Total = 0
FOR i = 0 to UBOUND(LookupArray)
Total = Total + CDEC(LookupArray(i))
NEXT i
RETURN Total
END FUNCTION
My Output is this:
12/01/2014 | 12/02/2014 | 12/03/2014 | 12/04/2014 | 12/05/2014 | Weekly totals|
1.63 | 1.79 | 1.75 | 1.59 | 1.41 | .87
The numbers corresponding to the days of the week are correct.
The number I should be getting for a total is
313/190.75 = 1.64
If I break it down and just look at the sum like this:
sum(Code.CalcPTD(Lookupset(FORMAT(Fields!REALDATE.Value,"Long Date"),FORMAT(Fields!CallbackDate.Value,"Long Date"),Fields!DailyHours.Value,"Hours_DataSet")))
I get the result of 352.50
If I count the number of items like this:
Count(Code.CalcPTD(Lookupset(FORMAT(Fields!REALDATE.Value,"Long Date"),FORMA(Fields!CallbackDate.Value,"Long Date"),Fields!DailyHours.Value,"Hours_DataSet")))
I get the result of 9
If I count distinct the number of items like this:
CountDistinct(Code.CalcPTD(Lookupset(FORMAT(Fields!REALDATE.Value,"Long Date"),FORMAT(Fields!CallbackDate.Value,"Long Date"),Fields!DailyHours.Value,"Hours_DataSet")))
I get the expected 5
I tried to write code for a distinct sum but it wouldn't return a single result but a series of 5 corresponding to the days of the week and I have to display in a single cell.
Any help would be appreciated. I know its kinda complicated. If you have questions or need further clarification please let me know.
So I figured out the answer on my own. To get a grand total of a variable within a dataset you can use SUM(fields!VarName.Value,"DataSet") and it does it for you.

how to set value of cell in multiple record - laravel, ajax

I use AJAX mechanism to set create or modify records in this table:
table:
id | item_type | item_id | creator_id | attitude
1 | exemplar | 3 | 33 | 1
2 | exemplar | 4 | 33 | 0
3 | exemplar | 3 | 35 | 1
In plain English: there are many exemplars to choose for one user. A given user can only set only one exemplar to value 1. In this particular case Exemplar #3 is active (attitude = 1). I want to set its "attitude" to 0 and in the same controller method where I have the below code.
The below code creates a new record for an exemplar which has never been chosen before, or changes the value of 'attitude column.
$user_id = Auth::user()->id;
$countatt = $exemplar->attitudes()->where('creator_id', $user_id)->first();
if (!$countatt)
{
$countatt = new Userattitude;
$countatt->creator_id = $user_id;
$countatt->item_type = 'exemplar';
$countatt->item_id = $exemplar_id;
}
$countatt->attitude = $value; // $value = 1
$countatt->save();
Problem to solve:
1. how, using the best practices, set all other records of the same user (creator_id) and exemplar_id to 0
My best guess isbe to put the below 4 lines before the code quoted above:
$oldactive= Exemplar::where('creator_id', $user_id)->where(exemplar_id, $exemplar_id)->first();
$zeroing_attitude= $oldactive->attitudes()->first();
$zeroing_attitude->attitude = 0;
$zeroing_attitude->save();
;
The above solution works only in case when there is only one exemplar with value of 'attitude' set to 1. But in the future I want to allow users to have multiple exemplars active. I am not familiar with Eloquent enough to rewrite the logic for multiple active Exemplars.
Sometimes there will be no active Exemplars set, which means that this collection would be empty
$oldactive= Exemplar::where('creator_id', $user_id)->where(exemplar_id, $exemplar_id)->first();
How should I skip executing the rest of the code in such case? By adding IF as below?
if($oldactive) {}
Thank you.
$oldactive= Exemplar::where('creator_id', $user_id)->where(exemplar_id,$exemplar_id)->first();
foreach($oldactive->attitudes() as $zeroing_attitude){
$zeroing_attitude->attitude = 0;
$zeroing_attitude->save();
}

WebFocus, two title columns and merging cells

If i have a table in a WebFocus Raport design
+--------+---------+--------+---------+
| left_1 | right_1 | left_2 | right_2 |
+--------+---------+--------+---------+
| v11 | p11 | v21 | v21 |
+--------+---------+--------+---------+
| v12 | p12 | v22 | v22 |
....
How to do a such table with syllabus column titles:
+-------+-------+-------+-------+
| One | Two |
+-------+-------+-------+-------+
| left | right | left | right |
+-------+-------+-------+-------+
| v11 | p11 | v21 | v21 |
+-------+-------+-------+-------+
| v12 | p12 | v22 | v22 |
....
Thank you
Sorry for the delay of the answer :)
To rename columns, with the AS command. Example:
TABLE FILE SYSTABLE
PRINT NAME
COMPUTE LEFT1/A3 = 'v11'; AS 'left';
COMPUTE RIGHT1/A3 = 'p11'; AS 'right';
COMPUTE LEFT2/A3 = 'v21'; AS 'left';
COMPUTE RIGHT2/A3 = 'p21'; AS 'right';
IF RECORDLIMIT EQ 10
END
To put the heading columns, you can work with the ACROSS command but it will be more tricky that if u use simply SUBHEAD. With the same example:
TABLE FILE SYSTABLE
PRINT NAME NOPRINT
COMPUTE LEFT1/A3 = 'v11'; AS 'left';
COMPUTE RIGHT1/A3 = 'p11'; AS 'right';
COMPUTE LEFT2/A3 = 'v21'; AS 'left';
COMPUTE RIGHT2/A3 = 'p21'; AS 'right';
IF RECORDLIMIT EQ 10
ON TABLE SUBHEAD
"<+0>One<+0> Two"
ON TABLE PCHOLD FORMAT HTML
ON TABLE SET HTMLCSS ON
ON TABLE SET STYLE *
UNITS=IN, PAGESIZE='Letter',
LEFTMARGIN=0.500000, RIGHTMARGIN=0.500000,
TOPMARGIN=0.500000, BOTTOMMARGIN=0.500000,
SQUEEZE=ON, GRID=OFF, ORIENTATION=LANDSCAPE, $
TYPE=REPORT,FONT='ARIAL',SIZE=9,$
TYPE=TABHEADING,HEADALIGN=BODY,$
TYPE=TABHEADING, LINE=1, ITEM=1, COLSPAN=2, SQUEEZE=ON,$
TYPE=TABHEADING, LINE=1, ITEM=2, COLSPAN=2, SQUEEZE=ON,$
ENDSTYLE
END
Hope it helps!
I'm not entirely sure if you load the headers as a field or if that is the field name
But this might help you
Define fields
TITL1/A3 = 'One';
TITL2/A3 = 'Two';
BLANK/A1 = '';
Edit the Left and Right title fields to remove the _1 or _2
Print the fields BY BLANK NOPRINT
Add
ON BLANK SUBHEAD
"
You can also add more rows to the subhead if you need more titles
You can easily do it by embedding HTML/CSS scripts in report(.fex) file.
just add the HTML/css code at the end of the file.
For eg.
-HTMLFORM BEGIN // to start styling your generated report table with HTML/CSS
TABLE tr
td:first-child // applies on 1st row ONLY.It can be td or th.
{
colspan = "2"; //to merge 2 columns
}
-HTMLFORM END //end HTML.
So the first row must have two cells having title "ONE" and "TWO"(in your case), and both cells must have property of colspan = "2"
Also you can refer:
Colspan propery from here
manipulating first row of table from here
Second option is to write the whole code in a file and save it in .htm/.html format and just insert the file in to WEBFOCUS(.fex) file.For eg.
-HTMLFORM BEGIN
-INCLUDE HTML_FILE.HTML
-HTMLFORM END
Hope it helps.Thanks.

PID control - value of process parameter based on PID result

I'm trying to implement a PID controller following http://en.wikipedia.org/wiki/PID_controller
The mechanism I try to control works as follows:
1. I have an input variable which I can control. Typical values would be 0.5...10.
2. I have an output value which I measure daily. My goal for the output is roughly at the same range.
The two variables have strong correlation - when the process parameter goes up, the output generally goes up, but there's quite a bit of noise.
I'm following the implementation here:
http://code.activestate.com/recipes/577231-discrete-pid-controller/
Now the PID seems like it is correlated with the error term, not the measured level of output. So my guess is that I am not supposed to use it as-is for the process variable, but rather as some correction to the current value? How is that supposed to work exactly?
For example, if we take Kp=1, Ki=Kd=0, The process (input) variable is 4, the current output level is 3 and my target is a value of 2, I get the following:
error = 2-3 = -1
PID = -1
Then I should set the process variable to -1? or 4-1=3?
You need to think in terms of the PID controller correcting a manipulated variable (MV) for errors, and that you need to use an I term to get to an on-target steady-state result. The I term is how the PID retains and applies memory of the prior behavior of the system.
If you are thinking in terms of the output of the controller being changes in the MV, it is more of a 'velocity form' PID, and the memory of prior errors and behavior is integrated and accumulated in the prior MV setting.
From your example, it seems like a manipulated value of -1 is not feasible and that you would like the controller to suggest a value like 3 to get a process output (PV) of 2. For a PID controller to make use of "The process (input) variable is 4,..." (MV in my terms) Ki must be non-zero, and if the system was at steady-state, whatever was accumulated in the integral (sum_e=sum(e)) would precisely equal 4/Ki, so:
Kp= Ki = 1 ; Kd =0
error = SV - PV = 2 - 3 = -1
sum_e = sum_e + error = 4/Ki -1
MV = PID = -1(Kp) + (4/Ki -1)Ki = -1Kp + 4 - 1*Ki = -1 +4 -1 = 2
If you used a slower Ki than 1, it would smooth out the noise more and not adjust the MV so quickly:
Ki = 0.1 ;
MV = PID = -1(Kp) + (4/Ki -1)Ki = -1Kp + 4 - 1*Ki = -1 +4 -0.1 = 2.9
At steady state at target (PV = SV), sum_e * Ki should produce the steady-state MV:
PV = SV
error = SV - PV = 0
Kp * error = 0
MV = 3 = PID = 0 * Kp + Ki * sum_e
A nice way to understand the PID controller is to put units on everything and think of Kp, Ki, Kd as conversions of the process error, accumulated error*timeUnit, and rate-of-change of error/timeUnit into terms of the manipulated variable, and that the controlled system converts the controller's manipulated variable into units of output.

Resources