Seems simple enough.  First let's convert your existing (HAVE) data listing and expected (EXPECT) data listings into datasets.  Then you just need to select the observations where recorded_time is le... See more...
Seems simple enough.  First let's convert your existing (HAVE) data listing and expected (EXPECT) data listings into datasets.  Then you just need to select the observations where recorded_time is less than or equal to last_visit. data have; input DMRN $ last_visit :date. UI recorded_time :date.; format last_visit recorded_time date9.; cards; 31 26AUG2021 0 06APR2018 31 26AUG2021 0 16JAN2020 31 26AUG2021 1 4MAY2021 31 26AUG2021 1 26MAY2022 33 24MAY2022 0 02MAR2020 33 24MAY2022 0 24MAY2022 35 01DEC2014 0 25MAR2013 35 01DEC2014 1 05JAN2015 ; data expect; input DMRN $ last_visit :date. UI recorded_time :date.; format last_visit recorded_time date9.; cards; 31 26AUG2021 0 06APR2018 31 26AUG2021 0 16JAN2020 31 26AUG2021 1 4MAY2021 33 24MAY2022 0 02MAR2020 33 24MAY2022 0 24MAY2022 35 01DEC2014 0 25MAR2013 ; data want ; set have; where recorded_time <= last_visit; run; proc compare data=want compare=expect; run;  
There is no way your expression     std(south and north) as sd_south_north can produce 8.4825  (or 18.4715998224301).        That's because the expression "south and north" is a logic... See more...
There is no way your expression     std(south and north) as sd_south_north can produce 8.4825  (or 18.4715998224301).        That's because the expression "south and north" is a logical expression yielding either a zero or one.  So std(south and north) would be getting the STD of a collection of 1's and 0's.    Please provide the code (and data) you used to produce the unexpected results you show.  
I already showed you how to do that.  You have to put those two "columns" of North and South into one "column" so that you can then use the MEAN() (or as it is commonly called in many SQL dialects AV... See more...
I already showed you how to do that.  You have to put those two "columns" of North and South into one "column" so that you can then use the MEAN() (or as it is commonly called in many SQL dialects AVERAGE()) aggregate function.  If your SQL dialect supports it you could also use a STD() aggregate function (by whatever name your SQL dialect chooses to use for it).   You could try crafting your own logic for generating statistics. The mean is just the sum over the count. So that is simple. (sum(south) + sum(north))/(count(south)+count(north)) as mean_south_north But the formula for the standard deviation is much more complicated.  You would need to remerge the mean back onto every observation, find the difference, etc. etc.   Also why the heck do you want the same value repeated onto every observation. Where are you going with this? Also how did you end up with that input data structured where you have the values for a single variable split into two variables?  It would be much easier in SQL if the data was structured with three variables (ID, DIRECTION, COUNT) and 16 observations instead of 5 variables and 4 observations.        
Hello @vijnad,   If all else fails, you can at least avoid the occurrence of the text "The SGRender Procedure" anywhere in the graph by post-processing the SVG file (which is a text file luckily)... See more...
Hello @vijnad,   If all else fails, you can at least avoid the occurrence of the text "The SGRender Procedure" anywhere in the graph by post-processing the SVG file (which is a text file luckily). In the example below I remove the text in a new SVG file named with the suffix "_clean", but you can replace the text by something more descriptive in the third argument of the TRANSTRN function as well. data _null_; infile "&figout/%sysfunc(tranwrd(&tlfname,-,_)).svg"; file "&figout/%sysfunc(tranwrd(&tlfname,-,_))_clean.svg"; input; _infile_=transtrn(_infile_,'The SGRender Procedure',trimn('')); put _infile_; run; If this still leaves unwanted elements in the graph (it did not in my tests), you can remove the corresponding SVG code by adding similar calls to the TRANSTRN function with a different second argument.
300 binary covariates most likely will take an extremely long time to fit such a model. I don't think there's any way around that. Even with an HP PROC. But there are optimization options and toleran... See more...
300 binary covariates most likely will take an extremely long time to fit such a model. I don't think there's any way around that. Even with an HP PROC. But there are optimization options and tolerance options for PROC HPGENSELECT, you could try those and see if anything helps (I'm guessing they would)   As far as what else to try, you could see which of the binary predictors are highly correlated with the binary response using a Chi-squared test (two way table in PROC FREQ with the CHISQ option will get you there) and just pick a few of the best binary predictors to use in the model.   Thinking out of the box, another approach is to use logistic Partial Least Squares with all 300 binary predictors. I have no doubt that even with 300 binary predictors it would finish much more quickly, and I would be surprised if it even took an hour. However, the only software to do this that I know of is in R (https://cran.r-project.org/web/packages/plsRglm/plsRglm.pdf)
If they are all of the same type (numeric or character does not matter) then a simple data step should do the job. data _null_; if 0 then set have; array __xx col: ; call symputx('colnum',di... See more...
If they are all of the same type (numeric or character does not matter) then a simple data step should do the job. data _null_; if 0 then set have; array __xx col: ; call symputx('colnum',dim(__xx)); stop; run; Otherwise you could try using the SAS dictionary metadata view/table to check. proc sql noprint; select count(*) format=32. into :colnum trimmed from dictionary.columns where libname='WORK' and memname='HAVE' and upcase(name) eqt 'COL' ; quit;
You did not include any ARRAY statements in your data step.  Read the documentation on how arrays work. So perhaps something like this: data ds; input id _den1-_den3 _num1-_num3; datalines; 1 ... See more...
You did not include any ARRAY statements in your data step.  Read the documentation on how arrays work. So perhaps something like this: data ds; input id _den1-_den3 _num1-_num3; datalines; 1 4 7 6 0 3 2 2 4 7 6 1 0 3 3 4 7 6 0 2 1 4 4 7 6 2 1 0 ; data want; set ds; array _den _den1-_den3; array _num _num1-_num3; array _low _low1-_low3; array _high _high1-_high3; array result $15 result1-result3; do i=1 to dim(_den); _pi = round((_num[i]/_den[i]),.0001); if _pi=0 then _low[i]=0; else _low[i]=round((1-betainv(.975,(_den[i]-_num[i]+1),_num[i])),.0001)*100; if _pi=1 then _high[i]=100; else _high[i]=round((1-betainv(.025,(_den[i]-_num[i]),_num[i]+1)),.0001)*100; result[i] = cats('[',put(_low[i], 5.1),',',put(_high[i], 5.1),']'); end; drop i _pi ; run; Result  
hours = intck("hour",start_date_time,end_date_time,"c");
DATA bins; length binnum 8. bin_desc $10.; INPUT binnum bin_desc $ @@; FORMAT bin_desc $10.; DATALINES; 1 [-20,-15) 2 [-5,0) 3 [0,5) 4 [5,10) 5 [10,15) 6 [15,20) 7 [20,25) 8 [25,30) 8 [30,35) 10 [35... See more...
DATA bins; length binnum 8. bin_desc $10.; INPUT binnum bin_desc $ @@; FORMAT bin_desc $10.; DATALINES; 1 [-20,-15) 2 [-5,0) 3 [0,5) 4 [5,10) 5 [10,15) 6 [15,20) 7 [20,25) 8 [25,30) 8 [30,35) 10 [35,40) 11 [40,45) 12 [45,50) 13 [55,60) 14 [60,65) 15 [65,70) 16 [70,75) 17 [75,80) 18 [80,85) 19 [85,90) 20 [90,95) 21 [95,100) 22 [100,HI) ; RUN; Formats control the display, at that point it is already read in. SAS defaults to 8 for characters so you want to specify a longer length.  I used 10 in my code above.    @PamG wrote: This seems like a very simple thing but I just can't seem to get it write.  When using the code below, SAS is truncating the last character wherever variable length is greater than 9.     DATA bins; INPUT binnum bin_desc $ @@; FORMAT bin_desc $10.; DATALINES; 1 [-20,-15) 2 [-5,0) 3 [0,5) 4 [5,10) 5 [10,15) 6 [15,20) 7 [20,25) 8 [25,30) 8 [30,35) 10 [35,40) 11 [40,45) 12 [45,50) 13 [55,60) 14 [60,65) 15 [65,70) 16 [70,75) 17 [75,80) 18 [80,85) 19 [85,90) 20 [90,95) 21 [95,100) 22 [100,HI) ; RUN;  
The DATEPART function assumes that you are extracting a Date value from a DATETIME value. DATETIME values are numbers of seconds and dates are numbers of days. So when you apply the Datepart to a dat... See more...
The DATEPART function assumes that you are extracting a Date value from a DATETIME value. DATETIME values are numbers of seconds and dates are numbers of days. So when you apply the Datepart to a date you get a very much smaller result. Basically any date between 01JAN1960 and 20JUL2196 will return a "datepart" value of 01JAN1960.   Your numeric value of 23480 is 14APR2024. So applying datepart to it will result in 01JAN1960. So you apparently have date values and using Datepart is not wanted or needed. Just apply the date9. format to that variable.
How are you merging? By Variable name or variable number?
Usually when I perform deployments I only perform the compute tier install and configuration once for the grid controller, and share that sas install and sas config to the grid nodes. When using a sha... See more...
Usually when I perform deployments I only perform the compute tier install and configuration once for the grid controller, and share that sas install and sas config to the grid nodes. When using a shared SAS Config you would not use sas.servers to start processes on any host but the initially configured node (e.g. grid controller). Then you'd use the individual service commands to start services on the node. Your configuration of having one compute tier on the grid controller and another for grid nodes is also valid though.
Converting a character string of '202201' to numeric is still not a SAS date value, so you won't be able to extract the year, quarter, etc. A SAS date is the number of days since January 1, 1960. In ... See more...
Converting a character string of '202201' to numeric is still not a SAS date value, so you won't be able to extract the year, quarter, etc. A SAS date is the number of days since January 1, 1960. In order to create a true SAS date, you can use the MDY function, along with the SUBSTR and PUT functions to parse out the year and month and convert to numeric, and then add a 'day' value of 1 for example:   data tab ; YrMth='201202'; tmonth=MDY(put(substr(YrMth,5),2.),1,put(substr(YrMth,1,4),4.)); /* create a numeric SAS date value */ year = year(tmonth); Quarter = "Q" || put(QTR(tmonth),1.); yr = put (year,z4.); inc_mnth = put(year(tmonth),z4.) || put(month(tmonth),z2.); month2=put(put(month(tmonth),z2.), $mth.); format tmonth yymm6.; run;   Does that help?
SAS doesn't appear to expose that message to ODS output.   If I had to do such I would also output the crosstabfreqs such as: ods output chisq=tst crosstabfreqs=freqs; Then summa... See more...
SAS doesn't appear to expose that message to ODS output.   If I had to do such I would also output the crosstabfreqs such as: ods output chisq=tst crosstabfreqs=freqs; Then summarize the small cell counts: Proc format library=work; value _5freq 0-<5= '<5' 5<-high ='5+' ; proc freq data=freqs; /* this where for a simple example like this gets the cells from the body of the table */ where _type_='11'; tables frequency /out=freqpct; format frequency _5freq.; run; and use that Freqpct data to create whatever you think should be added to that Chi square result set.    
Have a look at the Troubleshooting "Sort initialization failure" and "Sort execution failure" errors in Windows and UNIX environments for some suggestions on how to troubleshoot and fix this problem.... See more...
Have a look at the Troubleshooting "Sort initialization failure" and "Sort execution failure" errors in Windows and UNIX environments for some suggestions on how to troubleshoot and fix this problem.  
In Viya, select "Develop SAS Code" from the Applications menu (upper left - looks like a hamburger).  This will open SAS Studio.   Once you're in SAS Studio, you can use the Table Analysis Task t... See more...
In Viya, select "Develop SAS Code" from the Applications menu (upper left - looks like a hamburger).  This will open SAS Studio.   Once you're in SAS Studio, you can use the Table Analysis Task to perform a Chi-Sq test.  (Tasks are menu driven, well, tasks, & are available in SAS Studio on the left-side icon in SAS Studio).   The Table Analysis task is under Statistics-> Descriptive.   Hope that helps.
Maybe the program you posted differs from the program you actually ran. Without seeing the log, we can't tell. However, its easy to note that your first DATA step contains an END statement with no m... See more...
Maybe the program you posted differs from the program you actually ran. Without seeing the log, we can't tell. However, its easy to note that your first DATA step contains an END statement with no matching DO statement. So start by fixing that known error.
Yes. You can.   data have; set sashelp.class; if age >14 then super=cats('(*ESC*){style [font_style=italic]',name,'}'); else super=name; run; ods excel file='c:\temp\temp.xlsx'; proc report d... See more...
Yes. You can.   data have; set sashelp.class; if age >14 then super=cats('(*ESC*){style [font_style=italic]',name,'}'); else super=name; run; ods excel file='c:\temp\temp.xlsx'; proc report data=have nowd; column name age super; define name/display; run; ods excel close;  
Below two options how to achieve this.  For option 1: If your source data isn't already sorted by DMRN and DX_DATE then you need to add a Proc Sort. data have; input DMRN DX_DATE:date9. Age; ... See more...
Below two options how to achieve this.  For option 1: If your source data isn't already sorted by DMRN and DX_DATE then you need to add a Proc Sort. data have; input DMRN DX_DATE:date9. Age; format DX_DATE date9.; datalines; 2 09MAY2022 73 4 09APR2021 58 10 01JAN2017 60 10 03FEB2018 61 10 06JUN2018 61 13 08FEB2017 70 13 09JUL2017 70 13 12MAR2019 72 13 25DEC2019 72 ; /* option 1 */ data visit_cnt(keep=DMRN visits); set have; by DMRN DX_DATE; if first.dmrn then visits=1; else visits+1; if last.dmrn then output; run; data want1; merge have visit_cnt; by dmrn; if visits>=3; run; /* option 2 */ proc sql; create table want2 as select *, count(*) as visits from have group by dmrn having visits>=3 order by dmrn, dx_date ; quit;  
It appears you don't want to merge but to interleave the data sets - but then only keep rows with id's that exist in your first source table. data have1; input id y$; datalines; 1 10 2 20 ; data... See more...
It appears you don't want to merge but to interleave the data sets - but then only keep rows with id's that exist in your first source table. data have1; input id y$; datalines; 1 10 2 20 ; data have2; input id y$; datalines; 1 100 1 200 2 300 3 100 4 500 ; data want; set have1 (in=in1) have2; by id; retain keep_id; if first.id then keep_id=in1; if keep_id=1; drop keep_id; run; proc print data=want; run;