How to pause Execution in SAS for milliseconds - sas

How to pause an execution for 5 milliseconds in SAS?
Can I use "CALL SLEEP (0.005)"
I have checked the below link but its confusing
https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.2/lefunctionsref/n12ppys43orawkn1q0oxep4cmdk6.htm

The below shall stop the execution for 5 milliseconds in SAS.
data _null_;
call sleep(5);
run;
You can use the optional unit argument to specify the unit of time in seconds, which is applied to n. Default is .001 (milliseconds). You can change it to seconds if you like
data _null_;
call sleep(0.005,1);
run;
The above is equivalent to the former.

Sometimes it is better to try it out than to google:
data try_to_get_some_sleep;
format n unit z5.3 evening morning expect measure time18.9 diff percent7.2;
do unit = 5, 1, .5, .1, .01, .001;
do n = .1, .9, 1.1, 1.9, 2 ;
expect = n * unit;
evening = time();
call sleep (n, unit);
morning = time();
measure = morning - evening;
diff = (measure - expect) / expect;
output;
end;
end;
run;
results in
n unit evening morning expect measure diff
0.100 5.000 10:45:05.983414888 10:45:06.483422041 0:00:00.500000000 0:00:00.500007153 0.00%
0.900 5.000 10:45:06.483437061 10:45:10.984707117 0:00:04.500000000 0:00:04.501270056 0.03%
1.100 5.000 10:45:10.984720945 10:45:16.485454082 0:00:05.500000000 0:00:05.500733137 0.01%
1.900 5.000 10:45:16.485466003 10:45:25.984838009 0:00:09.500000000 0:00:09.499372005 (0.01%)
2.000 5.000 10:45:25.984853983 10:45:35.988686085 0:00:10.000000000 0:00:10.003832102 0.04%
0.100 1.000 10:45:35.988715887 10:45:36.088612080 0:00:00.100000000 0:00:00.099896193 (0.10%)
0.900 1.000 10:45:36.088624954 10:45:36.988639116 0:00:00.900000000 0:00:00.900014162 0.00%
1.100 1.000 10:45:36.988765001 10:45:38.089132071 0:00:01.100000000 0:00:01.100367069 0.03%
1.900 1.000 10:45:38.089145899 10:45:39.989645004 0:00:01.900000000 0:00:01.900499105 0.03%
2.000 1.000 10:45:39.989659071 10:45:41.989659071 0:00:02.000000000 0:00:02.000000000 0.00%
0.100 0.500 10:45:41.989671946 10:45:42.038803101 0:00:00.050000000 0:00:00.049131155 (1.74%)
0.900 0.500 10:45:42.038815975 10:45:42.488348961 0:00:00.450000000 0:00:00.449532986 (0.10%)
1.100 0.500 10:45:42.488362074 10:45:43.038013935 0:00:00.550000000 0:00:00.549651861 (0.06%)
1.900 0.500 10:45:43.038027048 10:45:43.987673044 0:00:00.950000000 0:00:00.949645996 (0.04%)
2.000 0.500 10:45:43.987685919 10:45:44.987751007 0:00:01.000000000 0:00:01.000065088 0.01%
0.100 0.100 10:45:44.987765074 10:45:44.996871948 0:00:00.010000000 0:00:00.009106874 (8.93%)
0.900 0.100 10:45:44.996876955 10:45:45.085994005 0:00:00.090000000 0:00:00.089117050 (0.98%)
1.100 0.100 10:45:45.086005926 10:45:45.195319891 0:00:00.110000000 0:00:00.109313965 (0.62%)
1.900 0.100 10:45:45.195332050 10:45:45.384675980 0:00:00.190000000 0:00:00.189343929 (0.35%)
2.000 0.100 10:45:45.384690046 10:45:45.585688114 0:00:00.200000000 0:00:00.200998068 0.50%
0.100 0.010 10:45:45.585701942 10:45:45.585707903 0:00:00.001000000 0:00:00.000005960 (99.4%)
0.900 0.010 10:45:45.585709095 10:45:45.595653057 0:00:00.009000000 0:00:00.009943962 10.5%
1.100 0.010 10:45:45.595659971 10:45:45.607652903 0:00:00.011000000 0:00:00.011992931 9.03%
1.900 0.010 10:45:45.607661009 10:45:45.626678944 0:00:00.019000000 0:00:00.019017935 0.09%
2.000 0.010 10:45:45.626689911 10:45:45.646678925 0:00:00.020000000 0:00:00.019989014 (0.05%)
0.100 0.001 10:45:45.646688938 10:45:45.646688938 0:00:00.000100000 0:00:00.000000000 ( 100%)
0.900 0.001 10:45:45.646689892 10:45:45.646689892 0:00:00.000900000 0:00:00.000000000 ( 100%)
1.100 0.001 10:45:45.646691084 10:45:45.647506952 0:00:00.001100000 0:00:00.000815868 (25.8%)
1.900 0.001 10:45:45.647507906 10:45:45.647620916 0:00:00.001900000 0:00:00.000113010 (94.1%)
2.000 0.001 10:45:45.647623062 10:45:45.650509119 0:00:00.002000000 0:00:00.002886057 44.3%

You can directly suspend a SAS session between steps using %SYSCALL SLEEP(... or %SYSFUNC(SLEEP(... NOTE: When using %SYSCALL you need to pass macro variables as the arguments, not numeric literal text.
Example:
%let duration = 5;
%let unit = 0.001;
data one; set sashelp.class; run;
%syscall sleep(duration,unit);
data two; set sashelp.cars; run;
or
data one; set sashelp.class; run;
%let rc = %sysfunc ( sleep ( 5, 0.001 ));
data two; set sashelp.cars; run;

Related

Looping through two lists in parallel

I have the following values
Time Value
3 0.03
6 0.04
9 0.05
12 0.06
As you can see, they move at steps of three and one respectively.
If I want to apply the following formula for each of them
X=sum(X,2/value)
What should I do?
I have tried as follows:
data want;
array my_array{0-10} $ _temporary_;
X=0;
Do i=1 to 5;
My_array(i)=sum(x,2/value)*i;
X= =sum(x,2/value)*i;
End;
Total=X;
Run;
However I am not looping through value, only through time (i goes from 1 to 4).
I would like to calculate for each time X applying the formula above, in order to have one column extra in the table above, then get the sum of these values.
In the example provided by Kermit in the answer below, the expected output (values under x should satisfy the formula mentioned above) would be the following:
time value x sum_x
3 0.03 200
6 0.04 300
9 0.05 360
12 0.06 400
Your expected results do not seem to match your explanation of the formula. You could use two arrays to allow you to pair the TIME and VALUE amounts.
data want;
array t [4] _temporary_ (3 6 9 12);
array v [4] _temporary_ (0.03 0.04 0.05 0.06);
do index=1 to dim(t);
time=t[index];
value=v[index];
x=sum(x,2/value)*index;
output;
end;
run;
Results
Obs index time value x
1 1 3 0.03 66.67
2 2 6 0.04 233.33
3 3 9 0.05 820.00
4 4 12 0.06 3413.33
If I understand correctly, time would be set on a quarterly basis and you would like to get the sum of X for each time. Next time, consider giving the expected output in your question.
data stage1;
do time=3 to 12 by 3;
do value = 0.03, 0.04, 0.05, 0.06;
x=(2/value)*time;
output;
end;
end;
run;
proc sort data=stage1;
by time value;
run;
data want;
do _n_=1 by 1 until(last.time);
set stage1;
by time;
sum_x=sum(sum_x, x);
output;
end;
run;
time value x sum_x
3 0.03 200 200
3 0.04 150 350
3 0.05 120 470
3 0.06 100 570
6 0.03 400 400
6 0.04 300 700
6 0.05 240 940
6 0.06 200 1140
9 0.03 600 600
9 0.04 450 1050
9 0.05 360 1410
9 0.06 300 1710
12 0.03 800 800
12 0.04 600 1400
12 0.05 480 1880
12 0.06 400 2280
EDIT after comments
Why would you use a do loop? Just perform element-wise multiplication within a table.
data want;
set have;
x=(2/value)*time;
retain sum_x 0;
sum_x=sum(sum_x, x);
output;
run;

Reading float type numbers from a .txt file and using them in formulas

I am trying to read numbers from a .txt file and use them in formulas within my code and output the results into another .txt file so I can use them easier. My problem is reading the 3000 lines of numbers and assigning them the variable to use in the formulas. The first column I need to the variable dt and the second column I would like it to be the variable i. For whatever reason, I can't get them to read correctly. Here is my code.
#include <stdlib.h>
#include <stdio.h>
void GetAcc(const float Acc[], const float Vel[], float Pos[], float dt);
void GetVel(const float Acc[], float Vel[], float dt);
int main()
{
float Position[3000]={0};
float Velocity[3000]={0};
float Acceleration[3000]={0};
float i;
float dt;
FILE *fp;
fp=fopen("M3 Array File.txt", "r+");
fscanf(fp,"%f",&dt);
fscanf(fp,"%f",&i);
GetVel(Acceleration,Velocity,dt);
GetAcc(Acceleration,Velocity,Position,dt);
for(i=0;i<3000;i++) fprintf(fp,"%3.3f\t%3.3f\t%3.3f\t%3.3f\n",dt*(float)i,Acceleration[i],Velocity[i],Position[i]);
fclose(fp);
return 0;
}
void GetVel(const float Acc[], float Vel[], float dt)
{
int i;
for(i=1;i<3000;i++)
{
Vel[i]=Vel[i-1]+Acc[i]*dt;
}
}
void GetAcc(const float Acc[], const float Vel[], float Pos[], float dt)
{
int i;
for(i=1;i<3000;i++)
{
Acc[i]=2*Pos[i]-Pos[i-1]-Vel[i-1];
}
}
Here is an example of what the file looks like.
0.000 0.000
0.001 0.000
0.002 0.000
0.003 0.000
0.004 0.000
0.005 0.000
0.006 0.000
0.007 0.000
0.008 0.000
0.009 0.000
0.010 0.000
0.011 0.000
0.012 0.000
0.013 0.000
0.014 0.000
0.015 0.000
0.016 0.000
0.017 0.000
0.018 0.000
0.019 0.000
0.020 0.000
0.021 0.000
0.022 0.000
0.023 0.000
0.024 0.000
0.025 0.000
0.026 0.000
0.027 0.000
0.028 0.000
0.029 0.000
0.030 0.002
0.031 0.003
0.032 0.005
0.033 0.005
0.034 0.005
0.035 0.005
0.036 0.005
0.037 0.006
0.038 0.008
0.039 0.009
0.040 0.011
0.041 0.012
0.042 0.012
0.043 0.012
0.044 0.012
0.045 0.014
0.046 0.015
0.047 0.017
0.048 0.018
0.049 0.020
0.050 0.021
0.051 0.023
0.052 0.025
0.053 0.026
0.054 0.028
0.055 0.029
0.056 0.031
0.057 0.032
0.058 0.034
0.059 0.035
0.060 0.037
0.061 0.040
0.062 0.043
0.063 0.046
0.064 0.049
0.065 0.052
0.066 0.054
0.067 0.055
0.068 0.057
0.069 0.060
0.070 0.063
0.071 0.066
0.072 0.069
0.073 0.072
0.074 0.075
0.075 0.078
0.076 0.081
0.077 0.084
0.078 0.087
0.079 0.091
0.080 0.095
0.081 0.100
0.082 0.104
0.083 0.109
0.084 0.114
0.085 0.117
0.086 0.120
0.087 0.123
0.088 0.127
0.089 0.132
0.090 0.137
0.091 0.141
0.092 0.146
0.093 0.150
0.094 0.155
0.095 0.161
0.096 0.167
0.097 0.173
0.098 0.179
0.099 0.184
0.100 0.189
0.101 0.193
0.102 0.199
0.103 0.206
0.104 0.212
0.105 0.218
0.106 0.224
0.107 0.230
0.108 0.236
0.109 0.242
0.110 0.250
0.111 0.258
0.112 0.265
0.113 0.273
0.114 0.281
0.115 0.288
0.116 0.296
0.117 0.304
0.118 0.311
0.119 0.319
0.120 0.327
0.121 0.334
0.122 0.342
0.123 0.350
0.124 0.359
0.125 0.368
0.126 0.377
0.127 0.387
0.128 0.396
0.129 0.405
0.130 0.414
0.131 0.423
0.132 0.433
0.133 0.442
0.134 0.451
0.135 0.460
0.136 0.471
0.137 0.482
0.138 0.492
0.139 0.503
0.140 0.514
0.141 0.525
0.142 0.535
0.143 0.546
0.144 0.557
0.145 0.569
0.146 0.581
0.147 0.594
0.148 0.606
0.149 0.618
0.150 0.630
0.151 0.643
0.152 0.655
0.153 0.667
0.154 0.680
0.155 0.692
0.156 0.706
0.157 0.719
0.158 0.733
0.159 0.747
0.160 0.761
0.161 0.775
0.162 0.788
0.163 0.802
0.164 0.816
0.165 0.830
0.166 0.845
0.167 0.861
0.168 0.876
0.169 0.891
0.170 0.907
0.171 0.922
0.172 0.937
0.173 0.953
0.174 0.969
0.175 0.986
0.176 1.003
0.177 1.020
0.178 1.037
0.179 1.054
0.180 1.071
0.181 1.088
0.182 1.104
0.183 1.121
0.184 1.140
0.185 1.158
0.186 1.177
0.187 1.195
0.188 1.213
0.189 1.232
0.190 1.250
0.191 1.269
0.192 1.287
0.193 1.307
0.194 1.327
0.195 1.347
0.196 1.367
0.197 1.387
0.198 1.407
0.199 1.427
0.200 1.447
0.201 1.468
0.202 1.489
0.203 1.511
0.204 1.532
0.205 1.554
0.206 1.575
0.207 1.597
0.208 1.618
0.209 1.640
0.210 1.663
0.211 1.686
0.212 1.709
0.213 1.732
0.214 1.755
0.215 1.778
0.216 1.801
0.217 1.824
0.218 1.848
0.219 1.873
0.220 1.898
0.221 1.922
0.222 1.947
0.223 1.971
0.224 1.996
0.225 2.020
0.226 2.045
0.227 2.071
0.228 2.097
0.229 2.123
0.230 2.149
0.231 2.175
0.232 2.201
0.233 2.227
0.234 2.255
0.235 2.283
0.236 2.310
0.237 2.338
0.238 2.365
0.239 2.393
0.240 2.421
0.241 2.448
0.242 2.476
0.243 2.505
0.244 2.534
0.245 2.563
0.246 2.592
0.247 2.622
0.248 2.651
0.249 2.680
0.250 2.709
0.251 2.740
0.252 2.770
0.253 2.801
0.254 2.832
0.255 2.862
0.256 2.893
0.257 2.924
0.258 2.954
0.259 2.987
0.260 3.019
0.261 3.051
0.262 3.083
0.263 3.116
0.264 3.148
0.265 3.180
0.266 3.212
0.267 3.246
0.268 3.280
0.269 3.313
0.270 3.347
0.271 3.381
0.272 3.415
0.273 3.448
0.274 3.482
0.275 3.517
0.276 3.553
0.277 3.588
0.278 3.623
0.279 3.659
0.280 3.694
0.281 3.729
0.282 3.764
0.283 3.800
0.284 3.836
0.285 3.873
0.286 3.910
0.287 3.947
0.288 3.984
0.289 4.021
0.290 4.057
0.291 4.094
0.292 4.133
0.293 4.171
0.294 4.209
0.295 4.248
0.296 4.286
0.297 4.324
0.298 4.363
0.299 4.401
0.300 4.439
0.301 4.479
0.302 4.519
0.303 4.559
0.304 4.599
0.305 4.639
0.306 4.679
0.307 4.719
0.308 4.758
0.309 4.800
0.310 4.841
0.311 4.883
0.312 4.924
0.313 4.965
0.314 5.007
0.315 5.048
0.316 5.090
0.317 5.131
0.318 5.174
0.319 5.217
0.320 5.260
0.321 5.303
0.322 5.346
0.323 5.389
0.324 5.432
0.325 5.475
0.326 5.518
0.327 5.562
0.328 5.607
0.329 5.651
0.330 5.696
0.331 5.740
0.332 5.785
0.333 5.829
0.334 5.874
0.335 5.918
0.336 5.963
0.337 6.009
0.338 6.055
0.339 6.101
0.340 6.147
0.341 6.193
0.342 6.239
0.343 6.285
0.344 6.331
0.345 6.378
0.346 6.426
0.347 6.473
You can use tokenize in c++
Spliting string into two with blank space
#include <vector>
#include <string>
#include <sstream>
#include <iterator>
string line;
istringstream buf(line);
istream_iterator<string> beg(buf), end;
vector<string> tokens(beg, end);
cout << "1st sub String : " << tokens[0];
cout << "2nd sub String : " << tokens[1];
Casting string to an int
int n;
stringstream num(tokens[1]);
num >> n;
These snippets might help you, Ref :
https://binaramedawatta.blogspot.com/2018/12/supporting-code-snippets-for-oop-take.html
https://www.geeksforgeeks.org/converting-strings-numbers-cc/
http://www.cplusplus.com/forum/beginner/87238/

Odds ratio for ordinal variables from PROC GENMOD

I have a set of data where I am creating a logistic regression model, looking at the odds of a binary outcome variable (Therapy), with Stage as an ordinal explanatory variable (0,1,2,3,4). A1c is a continuous variable. Because each patient has two eyes, I must use the repeated subject = patientID(EyeID) statement.
The following is my code:
PROC GENMOD data=new descend;
class patientID EyeID Stage (param = ordinal) Therapy (ref ="0") Gender(ref="M") Ethnic agegroup/ PARAM=ref;
model Therapy = Stage A1c gender AGEGROUP Ethnic/ dist=bin;
repeated subject=patientID(EyeID) / corr=unstr corrw;
lsmeans Stage / ilink exp oddsratio diff cl;
run;
Because Stage is an ordinal variable, I would like to get odds ratios for Stage 4 vs 0, 3 vs 0, 2 vs 0, etc, so I put in the lsmeans statement. However, I got this error: "WARNING: The model does not have a GLM parameterization. This parameterization is required for the TEST, LSMEANS, LSMESTIMATE, and
SLICE statement. These statements are ignored."
Any thoughts?
I have checked the design matrix for the class variables and they are correct.
Class Level Information
Class Value Design Variables
Stage 0 0 0 0 0
1 1.000 0 0 0
2 1.000 1.000 0 0
3 1.000 1.000 1.000 0
4 1.000 1.000 1.000 1.000
Gender F 1.000
M 0
Ethnic AA 1.000 0
As 0 1.000
C 0 0

How to plot a multiindex dataframe having suplots for the first level index?

I have a pandas multiindex dataframe with quarters 1-4 and hours 0-23 as the index.
The data Looks like this
quarter hour value1 value2 value3
1 0 0.06 0.47 0.50
1 1 0.65 0.04 0.65
1 2 0.58 0.10 0.60
1 3 0.51 0.07 0.17
...
4 20 0.82 0.17 0.96
4 21 0.08 0.98 0.09
4 22 0.73 0.43 0.73
4 23 0.99 0.85 0.42
How can I plot 4 linegraphs as subplots in a 2x2 arrangement having Q1 and Q4 on the top and Q2 and Q3 on the bottom?
I have been trying with
f, ((ax1, ax4), (ax2, ax3)) = plt.subplots(2, 2, sharex='col', sharey='row')
ax1.plot(df.loc[1])
But it doesnt seem to work.

How do I refer to the current line/observation number in a loop in the data step?

For example, I have data on various latencies that I iterate through and apply a linear function to, as shown: (the function is just an example here)
data latency;
input lat1 - lat20;
array cost[20];
array lat[20];
do x = 1 to 20;
cost[x] = lat[x] * 1.875;
end;
drop x;
datalines;
0.42 0.85 0.59 0.06 0.21 0.35 0.1 0.08 0.85 0.53 0.81 0.44 0.47 0.2 0.99 0.32 0.18 0.87 0.33 0.84
0.11 0.83 0.02 0.59 0.74 0.65 0.76 0.45 0.57 0.22 0.2 0.13 0.42 0.15 0.05 0.51 0.48 0.95 0.39 0.92
0.8 0.9 0.65 0.29 0.77 0.0 0.24 0.05 0.16 0.72 0.58 0.9 0.35 0.63 0.79 0.41 0.73 0.36 0.82 0.16
0.74 0.21 0.57 0.73 0.83 0.78 0.77 0.92 0.13 0.39 0.52 0.14 0.1 0.77 0.68 0.99 0.26 0.37 0.97 0.83
;
run;
How can I save a variable with the current observation number in each iteration of the loop, so that I can use it in calculations later?
I know that proc print will automatically print the observation number, but how do I access this and store it to a variable in the data step? Is there a way to do this as sas reads the datalines line by line?
I tried this, but then the obs variable is 2 for every observation.
data latency;
input lat1 - lat20;
obs = 1; * ADDED LINE;
array cost[20];
array lat[20];
do x = 1 to 20;
cost[x] = lat[x] * 1.875;
end;
obs = obs + 1; * ADDED LINE;
drop x;
datalines;
0.42 0.85 0.59 0.06 0.21 0.35 0.1 0.08 0.85 0.53 0.81 0.44 0.47 0.2 0.99 0.32 0.18 0.87 0.33 0.84
0.11 0.83 0.02 0.59 0.74 0.65 0.76 0.45 0.57 0.22 0.2 0.13 0.42 0.15 0.05 0.51 0.48 0.95 0.39 0.92
0.8 0.9 0.65 0.29 0.77 0.0 0.24 0.05 0.16 0.72 0.58 0.9 0.35 0.63 0.79 0.41 0.73 0.36 0.82 0.16
0.74 0.21 0.57 0.73 0.83 0.78 0.77 0.92 0.13 0.39 0.52 0.14 0.1 0.77 0.68 0.99 0.26 0.37 0.97 0.83
;
run;
proc print data=latency;
run;
This is a small example, but in reality I can't simply add a new variable that stores the line number to the start of each data line and read it in. That isn't practical for the actual data set.
You just need to add a retain statement so SAS doesn't reset obs to 0 at every new observation.
data latency;
retain obs 0;
obs = obs + 1;
...
run;
Your first attempt was very close. Try again, but this time replace this line:
obs = 1; * ADDED LINE;
With this:
retain obs 0; * ADDED LINE;
That way, your obs variable will be retained across your entire dataset instead of being reset to 1 each time.