NCO how can select days - cdo-climate

how can select days with Tmax exceeding the corresponding threshold (i.e., T > T90) in month with monthly precipitation lower than the 50th percentile
T90= 90th percentile
P50= 50th percentile
I have daily maximum temperature and daily precipitation
`dimensions:
lat = UNLIMITED ; // (34 currently)
lon = 42 ;
time = 360 ;
Parameter name = precip
float precip(lat,lon,time) ;`
`dimensions:
lat = UNLIMITED ; // (34 currently)
lon = 42 ;
time = 360 ;
Parameter name = tasmax
float tasmax(lat,lon,time) ;`
I try to do this in CDO

Related

How to calculate the running subtract

I have two table that Table1 contain item and balance, Table 2 contain item and consume, how to calculate the running balance as new column in table 2? (Balance - consume might be negative: shortage)
Table 1
Item
Balance
A
100
B
200
C
500
Table 2
Item
consume
A
10
A
20
A
20
B
120
B
100
C
100
C
100
C
200
Expected:
Item
consume
Running Balance
A
10
90
A
20
70
A
20
50
B
120
80
B
100
-20
C
100
400
C
100
300
C
200
100
Open your Table 2in the PowerQuery editor and from the Add Column tab select Index Column
Create a measure with the following expression:
running subtract =
VAR cursor =
MAX('Table 2'[Index])
VAR runtot =
CALCULATE(
SUM('Table 2'[consume]),
'Table 2'[Index] <= cursor
)
VAR balance =
LOOKUPVALUE('Table 1'[Balance],'Table 1'[Item], MAX('Table 2'[Item]))
RETURN
balance - runtot
Put everything together in a table visual

Multiple operations on a single value in SAS?

I'm trying to create a column that will apply to different interests to it based on how much each customer's cumulative purchases are. Not sure but I was thinking that I'd need to use a do while statement but entirely sure. :S
This is what I got so far but I don't know how to get it to perform two operations on one value. Such that, it will apply one interest rate until say, 4000, and then apply the other interest rate to the rest above 4000.
data cards;
set sortedccards;
by Cust_ID;
if first.Cust_ID then cp=0;
cp+Purchase;
if cp<=4000 then cb=(cp*.2);
if cp>4000 then cb=(cp*.2)+(cp*.1);
format cp dollar10.2 cp dollar10.2;
run;
What I'd like my output to look like.
You will want to also track the prior cumulative purchase in order to detect when a purchase causes the cumulative to cross the threshold (or breakpoint) $4,000. Breakpoint crossing purchases would be split into pre and post portions for different bonus rates.
Example:
Program flow causes retained variable pcp to act like a LAGged variable.
data have;
input id $ p;
datalines;
C001 1000
C001 2300
C001 2000
C001 1500
C001 800
C002 6200
C002 800
C002 300
C003 2200
C003 1700
C003 2500
C003 600
;
data want;
set have;
by id;
if first.id then do;
cp = 0;
pcp = 0; retain pcp; /* prior cumulative purchase */
end;
cp + p; /* sum statement causes cp to be implicitly retained */
* break point is 4,000;
if (cp > 4000 and pcp > 4000) then do;
* entire purchase in post breakpoint territory;
b = 0.01 * p;
end;
else
if (cp > 4000) then do;
* split purchase into pre and post breakpoint portions;
b = 0.10 * (4000 - pcp) + 0.01 * (p - (4000 - pcp));
end;
else do;
* entire purchase in pre breakpoint territory;
b = 0.10 * p;
end;
* update prior for next implicit iteration;
pcp = cp;
run;
Here is a fairly straightforward solution which is not optimized but works. We calculate the cumulative purchases and cumulative bonus at each step (which can be done quite simply), and then calculate the current period bonus as cumulative bonus minus previous cumulative bonus.
This is assuming that the percentage is 20% up to $4000 and 30% over $4000.
data have;
input id $ period MMDDYY10. purchase;
datalines;
C001 01/25/2019 1000
C001 02/25/2019 2300
C001 03/25/2019 2000
C001 04/25/2019 1500
C001 05/25/2019 800
C002 03/25/2019 6200
C002 04/25/2019 800
C002 05/25/2019 300
C003 02/25/2019 2200
C003 03/25/2019 1700
C003 04/25/2019 2500
C003 05/25/2019 600
;
run;
data want (drop=cumul_bonus);
set have;
by id;
retain cumul_purchase cumul_bonus;
if first.id then call missing(cumul_purchase,cumul_bonus);
** Calculate total cumulative purchase including current purchase **;
cumul_purchase + purchase;
** Calculate total cumulative bonus including current purchase **;
cumul_bonus = (0.2 * cumul_purchase) + ifn(cumul_purchase > 4000, 0.1 * (cumul_purchase - 4000), 0);
** Bonus for current purchase = total cumulative bonus - previous cumulative bonus **;
bonus = ifn(first.id,cumul_bonus,dif(cumul_bonus));
format period MMDDYY10.
purchase cumul_purchase bonus DOLLAR10.2
;
run;
proc print data=want;

Using do loops in sas

Assume you have a data file called VIRUS_PROLIF from an infectious disease research center. Each observation has 3 variables COUNTRY START_DATE, and DOUBLE_RATE, where START_DATE is the date that the Country registered its 100th case of COVID-19. For each country, DOUBLE_RATE is the number of days it takes for the number of cases to double in that country. Write the SAS code using DO UNTIL to calculate the date at which that Country would be predicted to register 200,000 cases of COVID-19.
data VIRUS_PROLIF;
INPUT COUNTRY $ start_date mmddyy10. num_of_cases double_rate ;
*here doubling rate is 100% so if day 1 had 100 cases day 2 will have 200;
Datalines;
US 03/13/2020 100 100
;
run;
data VIRUS_PROLIF1 (drop=start_date);
set VIRUS_PROLIF;
do until (num_of_cases>200000);
double_rate+1;
num_of_cases+ (num_of_cases*1);
end;
run;
proc print data=VIRUS_PROLIF1;
run;
The key concept you're missing here is how to employ the growth rate. That would be using the following formula, similar to interest growth for money.
If you have one dollar today and you get 100% interest it becomes
StartingAmount * (1 + interestRate) where the interest rate here is 100/100 = 1.
*fake data;
data VIRUS_PROLIF;
INPUT COUNTRY $ start_date mmddyy10. num_of_cases double_rate;
*here doubling rate is 100% so if day 1 had 100 cases day 2 will have 200;
Datalines;
US 03/13/2020 100 100
AB 03/17/2020 100 20
;
run;
data VIRUS_PROLIF1;
set VIRUS_PROLIF;
*assign date to starting date so both are in output;
date=start_date;
*save record to data set;
output;
do until (num_of_cases>200000);
*increment your day;
date=date+1;
;
*doubling rate is represented as a percent so add it to 1 to show the rate;
num_of_cases=num_of_cases*(1+double_rate/100);
*save record to data set;
output;
end;
*control date display;
format date start_date date9.;
run;
*check results;
proc print data=VIRUS_PROLIF1;
run;
The problem 200,000 < N0 (1+R/100) k can be solved for integer k without iterations
day_of_200K = ceil (
LOG ( 200000 / NUM_OF_CASES )
/ LOG ( 1 + R / 100 )
);

How to indent or center a PROC REPORT column output to RTF?

This is the output that I need in RTF format:
**DEMOGRAPHICS A-B**
Age
n 18
Mean 30.4
SD 6.29
Min 18
Median 30.5
Max 39
but I am getting this result:
**DEMOGRAPHICS A-B**
Age
n 18
Mean 30.4
SD 6.29
Min 18
Median 30.5
Max 39
How do I left align age and center the remaining variables?
Here is my code:
proc report data = FINAL2 split = "#"
STYLE(REPORT)=[BACKGROUND=WHITE BORDERCOLOR=BLACK BORDERWIDTH=0.1 ASIS=on FRAME=HSIDES RULES=GROUPS]
STYLE(HEADER)=[BACKGROUND=WHITE];
COLUMN DESC STAT1;
define DESC / "Demographic Characteristics" style(column)=[cellwidth=30%] style(header)=[just=left asis = on] ;
define STAT1 /"A - B#(N=18)" style(column header)=[cellwidth = 20%] style(header)=[just = left asis = yes];
You can use a compute block to do this. This would be executed per row but you could conditionally apply a column-specific style from there based on the variable's value being 'Age' or something else.
For example (you can add this after the define statements in your report step):
compute desc;
if desc ^= 'Age' then
call define(_COL_, "style", "style=[paddingleft=3em]");
endcomp;
This would apply a 3em padding to each desc column that doesn't match 'Age'.

Generate percent change between annual observations in Stata?

How do I use the gen or egen commands to generate the percent change between observations for different years in Stata? For example, I have observations for 1990 through 2010, each with a different value for expenditures, and I'm trying to generate a new observation with the percent change from 1990-1991, 1991-1992, etc.
// Here's an example with another measure of growth:
clear
set obs 100
gen year = _n + 1959
gen expenditure = _n^(1/3) + runiform()
line expenditure year, yti("Synthetic data example")
// From Statalist:
bys year: g expendituregrowth=100*(expenditure[_n]-expenditure[_n-1])/expenditure[_n-1]
// Also:
gen expenditure_gr = (expenditure/expenditure[_n-1] - 1)*100 // growth rate for expenditure
gen expenditure_bl = 100*expenditure/expenditure[1] // baseline growth rate for expenditure; base 100 = 1960
line expenditure_gr year, yti("Growth rate")
line expenditure_bl year, yti("Growth rate (base 100 = 1960)")
// The computation of expenditure_gr is what I think you are looking for.
// If your data are well-formed, use Stata with time series and get the growth rate easily:
tsset year, delta(1)
cap drop expenditure_gr
gen expenditure_gr = D.expenditure / 100*L.expenditure