Précédent   Forum des professionnels en informatique > Logiciels > Solutions d'entreprise > Business Intelligence > SAS > SAS Base
SAS Base Forum d'entraide sur SAS base : étape data, procédures non statistiques, procédures non graphiques, SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 21/06/2011, 14h16   #1
Membre du Club
 
Inscription : janvier 2009
Messages : 98
Détails du profil
Informations forums :
Inscription : janvier 2009
Messages : 98
Points : 66
Points : 66
Par défaut Calcul cumul sur période glissante

Bonjour,

J'aimerai savoir comment il est possible de calculer en SAS un cumul sur période glissante.
ex période glissante = 5j
j1 100
j2 50
j3 40
j4 10
j5 20
j6 200
j7 60

cumul glissant j1 = 100
cumul glissant j2 = 150
cumul glissant j3 = 190
cumul glissant j4 = 200
cumul glissant j5 = 220
cumul glissant j6 = 320 (220 + 200 - 100)
cumul glissant j7 = 330 (320 + 60 - 50)

Pour l'instant j'ai fait une boucle while qui boucle sur les lignes tant que la période ne dépasse pas 5. Donc pour chaque ligne je boucle 5 fois. Cela marche mais je ne trouve pas cela optimisé.
ex c_j7 = j7 + j6 + j5 + j4 + j3

NB : je ne peux pas passer par un lag.

merci de votre aide
lhonolulu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/06/2011, 15h26   #2
Rédacteur
 
Homme Stéphane
Consultant et formateur SAS et Cognos
Inscription : avril 2009
Messages : 1 791
Détails du profil
Informations personnelles :
Nom : Homme Stéphane
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Consultant et formateur SAS et Cognos
Secteur : Conseil

Informations forums :
Inscription : avril 2009
Messages : 1 791
Points : 4 012
Points : 4 012
la vieille méthode mixe le RETAIN et la fonction SUM

Code :
1
2
3
4
5
   DATA a;
      SET a;
      retain xsum;
      xsum = sum( xsum, x );
   run;
La vieille méthode plus astucieuse :
Code :
1
2
3
4
   DATA a;
      SET a;
      xsum + x;
   run;
Je regarderai la proc EXPAND si j'étais toi :

Code :
1
2
3
   proc expand DATA=a out=a method=none;
      convert x=xsum / transform=( sum );
   run;
__________________
N'oubliez pas de cliquer sur lorsque votre problème est réglé !

Moteur de recherche dans les papiers SAS
datametric est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/06/2011, 16h05   #3
Membre du Club
 
Inscription : janvier 2009
Messages : 98
Détails du profil
Informations forums :
Inscription : janvier 2009
Messages : 98
Points : 66
Points : 66
la méthode du retain va marcher dans mon exemple jusqu'en j5.
mais à partir de j6 cela ne marchera plus car je dois soustraire de la somme la j1 (je précise que je ne peux pas faire un lag5).

proc expand je vais regarder je ne connais pas.
mais merci quand meme
s'il y a d'autres idées
lhonolulu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/06/2011, 16h33   #4
Nouveau Membre du Club
 
Homme Gaëtan
Inscription : avril 2011
Messages : 29
Détails du profil
Informations personnelles :
Nom : Homme Gaëtan
Localisation : France

Informations forums :
Inscription : avril 2011
Messages : 29
Points : 26
Points : 26
En utilisant la méthode du retain ça marche très bien, il faut juste s'arranger pour soustraire la valeur correspondante au lag5 (et d'ailleurs j'aimerais bien savoir pourquoi on ne peut pas utiliser cette fonction puisque si je ne me trompe pas elle est disponible sans module complémentaire, non ?).
Et donc pour avoir cette valeur un simple merge suffit :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
DATA test;
input id$ num;
cards;
j1 100
j2 50
j3 40
j4 10
j5 20
j6 200
j7 60
;
run;
 
DATA toto;
SET test;
IF _n_ > 5 then merge test (RENAME= (num=num2) keep = num);
retain somme;
somme=sum(somme,num,-num2);
run;
et si tu peux utiliser la proc expand il me semble qu'il y a justement une option LAG dedans que tu pourrais utiliser aussi.
boutchiwah est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/06/2011, 16h50   #5
Membre du Club
 
Inscription : janvier 2009
Messages : 98
Détails du profil
Informations forums :
Inscription : janvier 2009
Messages : 98
Points : 66
Points : 66
Je ne peux pas utiliser de lag car je ne connais pas le nombre de ligne qu'il y a aura dans ma période glissante.
en gros je peux avoir dans mon cas
j1 100
j1 50
j2 10
pas de j3
j4 20
j4 30

je ne peux pas non plus faire agréger mes "j1" et "j4" ensemble. Derrière j1, j2...j'ai un datetime et non une date.
Ma période glissante n'est pas en jour mais imaginons de 30 min. Je ne sais pas combien d'observatiosn il y a eu les 30 dernières minutes. De plus cela changera à chaque fois. donc pas de lag.

Dans l'idée c'est comme ton merge avec if.
Par contre je ne connais pas du tout cette syntaxe. du set + merge avec un if dedans et sans "by". ca semble usine à gaz non ?
lhonolulu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/06/2011, 17h08   #6
Nouveau Membre du Club
 
Homme Gaëtan
Inscription : avril 2011
Messages : 29
Détails du profil
Informations personnelles :
Nom : Homme Gaëtan
Localisation : France

Informations forums :
Inscription : avril 2011
Messages : 29
Points : 26
Points : 26
oui alors là si tu n'as pas le même nombre d'observation par période mon programme ne fonctionnera plus je pense ...

et sinon pour mon set + merge ça marche comme un merge mais à partir de la ligne 5.
là j'ai bidouillé un truc car j'avais la flemme de chercher comment faire avec les options (surement qu'avec l'option firstobs on peut arriver à un truc mais je vois pas comment)
boutchiwah est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/06/2011, 11h49   #7
Membre éclairé
 
Homme
statisticien
Inscription : mai 2011
Messages : 212
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : statisticien
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : mai 2011
Messages : 212
Points : 319
Points : 319
Bonjour

Je vais te proposer une solution d'après ce que je crois avoir compris de ton problème... Mais il est possible que j'ai mal compris.

En effet des choses sont un peu flous pour moi comme ta variable date qui est un "datetime" et pas une date, j'avoue n'avoir pas trop compris.

Ce que j'ai compris...

1- C'est que tu as des observations discretes d'un temps continu dans tes observations (genre t=4523.2653).

2- Un nombre de mesure variables par jour, voir absentes.

3- Et que tu voudrais faire le cumul de ta variable d'intéret entre ]t-5t,t] (tu remarquera l'ouverture des crochets gauche sur la gauche, si tu veux [t-5,t] il vaudra modifier très légèrement le code).

Je me suis fait un petit jeu de données

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
 
DATA base;
input t val;
datalines;
0.3578663	20
0.554034272	26
0.594907992	14
0.67850168	19
1.051024021	37
1.840402176	10
2.10110918	17
2.944497658	15
3.50225009	14
5.680295515	12
5.721597295	48
5.842153921	11
5.940984075	18
6.159698725	4
6.34446108	2
8.302713505	11
8.51342009	14
8.923785552	32
9.808417324	17
10.3033697	0
10.40308743	3
10.45904821	13
11.64017362	45
11.94454034	30
12.0784477	13
12.47084792	4
13.07471074	28
13.19714919	12
14.02846277	13
14.11464639	29
14.23912768	14
14.28419683	0
14.58878233	10
14.66393865	15
16.20378219	11
16.25928535	46
16.74232079	15
17.54821753	11
18.48870469	11
18.71186342	16
19.3236094	28
19.44425252	14
20.58774388	4
20.76121509	33
20.76938894	12
20.89824356	4
21.67763102	14
23.91089795	28
24.05123006	30
24.88861472	30
25.10785009	32
26.61662099	5
26.85459653	11
27.65481824	28
28.23137958	25
28.43845722	34
29.45190817	27
29.60674103	27
30.17350361	29
30.69982294	1
31.01799721	29
31.13823027	32
31.2439203	27
31.95109399	1
32.20236372	28
32.2603392	15
32.31340337	18
32.47965509	19
33.3716565	17
33.5980744	35
34.50297194	17
35.00761775	28
35.61717254	14
35.91431817	28
36.19842474	5
36.51371672	15
36.98261477	29
37.24483335	20
37.42121912	26
37.82217987	30
37.97625237	17
38.0425728	18
38.30098806	23
38.46198495	4
38.70546671	11
38.90349151	22
39.09948865	11
40.6919711	31
40.70716618	32
41.31674469	10
41.69986614	16
42.29903899	32
43.06921241	32
43.72037362	20
43.89506514	14
;run;
Quelques lignes de codes

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
 
DATA base; SET base;
retain sum;
sum+val;
output ;
t=t+5;sum_d=sum;type="decalage+5";output ;
run;
proc sort DATA=base; BY t;run;
DATA base; SET base;
retain v;
IF _n_=1 then do;v=0;sum_d=0;end;
else	do; IF sum_d=. then sum_d=v;else v=sum_d;
		end;
IF type="decalage+5" then DELETE;
cumul_5j=sum-sum_d;
DROP sum sum_d v type;
run;
ce qui donne au final quelque chose comme ça

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
 
                                                   Obs       t       val    cumul_5j
 
                                                     1     0.3579     20        20
                                                     2     0.5540     26        46
                                                     3     0.5949     14        60
                                                     4     0.6785     19        79
                                                     5     1.0510     37       116
                                                     6     1.8404     10       126
                                                     7     2.1011     17       143
                                                     8     2.9445     15       158
                                                     9     3.5023     14       172
                                                    10     5.6803     12       105
                                                    11     5.7216     48       153
                                                    12     5.8422     11       164
                                                    13     5.9410     18       182
                                                    14     6.1597      4       149
                                                    15     6.3445      2       151
                                                    16     8.3027     11       120
                                                    17     8.5134     14       120
                                                    18     8.9238     32       152
                                                    19     9.8084     17       169
                                                    20    10.3034      0       169
                                                    21    10.4031      3       172
                                                    22    10.4590     13       185
                                                    23    11.6402     45       135
                                                    24    11.9445     30       165
                                                    25    12.0784     13       178
                                                    26    12.4708      4       182
                                                    27    13.0747     28       210
                                                    28    13.1971     12       222
                                                    29    14.0285     13       178
                                                    30    14.1146     29       207
                                                    31    14.2391     14       221
                                                    32    14.2842      0       221
                                                    33    14.5888     10       231
                                                    34    14.6639     15       246
                                                    35    16.2038     11       224
                                                    36    16.2593     46       270
                                                    37    16.7423     15       240
Ensuite pour arriver au cumul du jour et 5 jours passés, il reste des choses a définir, là ce n'est plus de la programmation mais de la méthodologie statistique.
En tout cas à cette étape tu dispose pour chaque observation le total cumul entre le temps courant t (par exemple t=16.2038) jusqu'à t-5 exclu(soit t=11.2038+epsilon de temps) et donc une fois que tu aura défini exactement le resultat statistique que tu veux obtenir, il ne sera plus trop compliqué d'y parvenir.
jerome_pdv2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/06/2011, 11h58   #8
Expert Confirmé
 
Avatar de olivier.decourt
 
Homme Olivier Decourt
Formateur en informatique
Inscription : avril 2008
Messages : 1 467
Détails du profil
Informations personnelles :
Nom : Homme Olivier Decourt
Âge : 34
Localisation : France

Informations professionnelles :
Activité : Formateur en informatique
Secteur : Conseil

Informations forums :
Inscription : avril 2008
Messages : 1 467
Points : 2 823
Points : 2 823
Salut.
Ca va être compliqué avec une étape DATA puisqu'on ne sait pas à l'avance combien de lignes on doit retenir. Je te propose une solution en SQL, en joignant la table avec elle-même pour sélectionner les valeurs dans la dernière demi-heure et les sommer.
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/* données bidon pour essayer */
DATA work.test (DROP=i h nbVal) ;
  FORMAT heure TIME8. ;
  DO h=0 TO "12:00:00"T BY 3600 ;
    nbVal = ROUND(RANUNI(1)*10) ; /* nombre de valeurs par heure de 0 à 10 */
	DO i=1 TO nbVal ;
	  heure = h + i*(3600/nbVal) ;
	  x = ABS(ROUND(RANNOR(1)*100,10)) ;
	  OUTPUT ;
	END ;
  END ;
RUN ;
PROC SQL ;
  CREATE TABLE work.sommes AS
    SELECT b.*,
	       SUM(s.x) AS glissant
	FROM work.test AS b
	  LEFT JOIN
	     work.test AS s
	  ON s.heure BETWEEN b.heure AND b.heure-30*60 /* dans la dernière 1/2 heure */
	GROUP BY b.heure, b.x
  ;
QUIT ;
Bon courage.
Olivier
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/06/2011, 10h34   #9
Membre du Club
 
Inscription : janvier 2009
Messages : 98
Détails du profil
Informations forums :
Inscription : janvier 2009
Messages : 98
Points : 66
Points : 66
Merci pour vos réponses c'est exactement ce que je voulais dans les deux cas.
lhonolulu est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 22h50.


 
 
 
 
Partenaires

Hébergement Web