BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
brophymj
Quartz | Level 8

Thanks Astounding. 

 

I made the change (just replaced price with price_) but I'm still getting errors in the log. If you run the code below do you get errors?

 

data have;
infile datalines;
input Year Month $ Week Day Price;
datalines;
2015 Jan 1 1 98
2015 Jan 1 2 87
2015 Jan 1 3 86
2015 Jan 1 4 86
2015 Jan 1 5 86
2015 Jan 1 6 87
2015 Jan 1 7 88
;
run;

proc transpose data=have prefix=price_ out=want;
by year month week;
var price;
run;

data want;
set want;
array price_ {*};
do i=1 to dim(price_) - 1;
do j=i+1 to dim(price_);
max_change = max(max_change, price_{j} / price_{i} - 1);
end;
end;
run;

Astounding
PROC Star

OK, let's try this additional change:

 

array price_ {*} price_: ;

rogerjdeangelis
Barite | Level 11
Create array of price change combinations

This is best done in IML or R.

In order to print the max on the first record I had to load a two dimesional array and
find the max of all elements and then load load and output a seven element
array

redirect to this message
https://goo.gl/6gxqsO
https://communities.sas.com/t5/Base-SAS-Programming/Create-array-of-price-change-combinations/m-p/347274

HAVE
====

Up to 40 obs WORK.HAVE total obs=7

Obs    DAY    PRICE

 1      1     100.0
 2      2     101.5
 3      3     103.0
 4      4     104.5
 5      5     106.0
 6      6     107.5
 7      7     109.0

WANT
====

DETAILS

 DAY1  PCT2 = 100*(Price[2]/Price[1] - 1) ... PCT7=100*(Price[7]/Price[1] - 1)
 ..
 DAY6  PCT7 = 100*(Price[7]/Price[6] - 1) 100*(109/107.5 - 1) = 1.3953488372


*
 ___  __ _ ___
/ __|/ _` / __|
\__ \ (_| \__ \
|___/\__,_|___/

;

 DAY    BASE     PCT1    PCT2    PCT3    PCT4    PCT5    PCT6    PCT7  MAX

 1.0    100.0     .      1.5     3.0     4.5     6.0     7.5     9.0   9.0
 2.0    101.5     .       .      1.5     3.0     4.4     5.9     7.4    .
 3.0    103.0     .       .       .      1.5     2.9     4.4     5.8    .
 4.0    104.5     .       .       .       .      1.4     2.9     4.3    .
 5.0    106.0     .       .       .       .       .      1.4     2.8    .
 6.0    107.5     .       .       .       .       .       .      1.4    .  PCT7 =100*(109/107.5 - 1) = 1.3953488372

*                         ____
__      ___ __  ___      |  _ \
\ \ /\ / / '_ \/ __|_____| |_) |
 \ V  V /| |_) \__ \_____|  _ <
  \_/\_/ | .__/|___/     |_| \_\
         |_|
;
 40 obs WORK.WANT total obs=6

Obs    DAY    PRICE    PCT2    PCT3    PCT4    PCT5    PCT6    PCT7    MAX

 1     1.0    100.0    1.5     3.0     4.5     6.0     7.5     9.0     9.0
 2     2.0    101.5     .      1.5     3.0     4.4     5.9     7.4      .
 3     3.0    103.0     .       .      1.5     2.9     4.4     5.8      .
 4     4.0    104.5     .       .       .      1.4     2.9     4.3      .
 5     5.0    106.0     .       .       .       .      1.4     2.8      .
 6     6.0    107.5     .       .       .       .       .      1.4      .



FULL SOLUTION
=============

*                _                  _       _
 _ __ ___   __ _| | _____        __| | __ _| |_ __ _
| '_ ` _ \ / _` | |/ / _ \_____ / _` |/ _` | __/ _` |
| | | | | | (_| |   <  __/_____| (_| | (_| | || (_| |
|_| |_| |_|\__,_|_|\_\___|      \__,_|\__,_|\__\__,_|

;

options validvarname=upcase;
libname sd1 "d:/sd1";
data sd1.have;
retain day price;
input Price;
day=_n_;
cards4;
100
101.5
103
104.5
106
107.5
109
;;;;
run;quit;

*_        ______  ____        ____
\ \      / /  _ \/ ___|      |  _ \
 \ \ /\ / /| |_) \___ \ _____| |_) |
  \ V  V / |  __/ ___) |_____|  _ <
   \_/\_/  |_|   |____/      |_| \_\

;

%utl_submit_wps64('
libname sd1 "d:/sd1";
options set=R_HOME "C:/Program Files/R/R-3.3.2";
libname wrk "%sysfunc(pathname(work))";
libname hlp "C:\Program Files\SASHome\SASFoundation\9.4\core\sashelp";
proc r;
submit;
source("C:/Program Files/R/R-3.3.2/etc/Rprofile.site", echo=T);
library(haven);
have<-t(read_sas("d:/sd1/have.sas7bdat")[,2]);
mat=have[rep(seq_len(nrow(have)), each=6),];
bas<-cbind(have[1:6],mat);
fin<-100*(bas[,2:8]/bas[,1] - 1);
fin[lower.tri(fin)] <- NA;
fin[ row(fin) == col(fin) ] <- NA;
fin[1,1]<-max(fin,na.rm = TRUE);
endsubmit;
import r=fin data=wrk.fin;
run;quit;
');

data want;
  retain day price pct2-pct7 max;
  merge sd1.have(obs=6) fin(rename=(v2-v7=pct2-pct7 v1=max));
run;quit;

proc print data=want width=min;
 format _numeric_ 8.1;
run;quit;

*          _       _   _
 ___  ___ | |_   _| |_(_) ___  _ __
/ __|/ _ \| | | | | __| |/ _ \| '_ \
\__ \ (_) | | |_| | |_| | (_) | | | |
|___/\___/|_|\__,_|\__|_|\___/|_| |_|

;

%symdel obs /nowarn;
libname sd1 "d:/sd1";
data want;
  retain day base maxfin;
  if _n_=0 then do;
     rc=%sysfunc(dosubl('proc sql noprint;select count(*) into :obs separated by ""  from sd1.have;quit;'));
  end;
  do rec=1 to &obs;
     array pry[&obs] jan1-jan&obs;
     array pct[&obs] pct1-pct&obs;
     array fin[&obs,&obs] fin1-fin%eval(%eval(&obs * &obs));
     set sd1.have;
     pry[rec]=price;
  end;
  do day=1 to &obs - 1;
    do mat=day+1 to &obs;
        fin[day,mat]=100*pry[mat]/pry[day] -100;
        base=pry[day];
    end;
  end;
  maxfin=max(of fin[*]);
  put maxfin=;
  do day=1 to &obs - 1;
    do mat=1 to &obs;
       fins+1;
       pct[mat]=fin[day,mat];
    end;
    if day ne 1 then maxfin=.;
    output;
  end;
  keep day base  pct: maxfin;
run;quit;

proc print data=want width=min;
 format _numeric_ 8.1;
run;quit;
Ksharp
Super User
you really should take on IML code.
It is very easy for IML.




data have;
infile datalines;
input Year Month $ Week Day Price;
datalines;
2015 Jan 1 1 100
2015 Jan 1 2 101.5
2015 Jan 1 3 103
2015 Jan 1 4 104.5
2015 Jan 1 5 106
2015 Jan 1 6 107.5
2015 Jan 1 7 109
;
run;

proc iml;
use have;
read all var{price};

lag=lag(price,1:nrow(price)-1);
dif=dif(price,1:nrow(price)-1);
d=dif/lag; 

w=j(nrow(d)-1,ncol(d),.);
do i=1 to ncol(d);
 w[1:nrow(d)-i,i]=d[i+1:nrow(d),i];
end;
want=j(nrow(d)-1,ncol(d),.);
do i=1 to nrow(w);
 want[i,i:ncol(d)]=w[i,1:(ncol(d)-i+1)];
end;

create temp from want;
append from want;
close;
quit;

data want;
 merge have temp;
 max=max(of col:);
run;
proc print;run;



brophymj
Quartz | Level 8

I would but I don't have the SAS/IML package. This code doesn't work on my 9.3 SAS version. 

ballardw
Super User

@Ksharp The op seems unable to describe the process or the result in non-speadsheet terms. This is a continuation of https://communities.sas.com/t5/Base-SAS-Programming/Max-price-change-within-interval-i-e-30-days-or-...

 

 

brophymj
Quartz | Level 8

I thought I described it quite clearly. I don't think your comment helps. 

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 16. Read more here about why you should contribute and what is in it for you!

Submit your idea!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 21 replies
  • 1962 views
  • 1 like
  • 6 in conversation