IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SAS Base Discussion :

Ventiler une table en plusieurs tables


Sujet :

SAS Base

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 155
    Points : 37
    Points
    37
    Par défaut Ventiler une table en plusieurs tables
    Bonjour,
    je reçoi une table "A" qui change du nombre de ligne a chaque fois.
    une fois je la reçoi avec par exemple 10.000 lignes d'autre fois avec 20.000 ......50.000......100.000...le nombre de ligne est variable.
    Depuis la table "A" je veux sortir plusieurs table dans chaqu'une des table 10.000 lignes.
    Sachant aussi que la table "A" contient une colonne OBS =elle donne le numéro de ligne
    Exemple:
    Si la table "A"=50.000 lignes ça va me donner :
    A1=10.000 lignes avec OBS du 1 ....à 10.000 et
    A2=10.000 lignes avec OBS du 1 ....à 10.000 et
    A3=10.000 lignes avec OBS du 1 ....à 10.000 et
    A4=10.000 lignes avec OBS du 1 ....à 10.000 et
    A5=10.000 lignes avec OBS du 1 ....à 10.000 et
    Dans ce but j'ai fais ce programme avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    data toto1 toto2 toto3 toto4 toto5 ;set A ;
    if _N_<=10.000 then output toto1;
    if (_N_ >10.000 and _N_<=20.000) then do ;numOBS=numOBS-10.000 ;output toto2;;end ;
    if (_N_ >20.000 and _N_<=30.000) then do; numOBS=numOBS-20.000 ;output toto3;end;
    if (_N_ >30.000 and _N_<=40.000) then do; numOBS=numOBS-30.000 ;output toto4;end;
    if (_N_ >40.000 and _N_<=50.000) then do; numOBS=numOBS-40.000 ;output toto5;end;
    Mon prblème c'est que si je recçoi une table "A" avec seulement 5000 (juste un exemple) je ne veux pas qu'il m'affiche toto2 et toto 3 et toto4 et toto5 si ils ont pas de lignes et je ne sais pas comment lui dire ça !!
    J'ai essayé avec le count mais je n'arrive pas .
    Merci pour votre aide

  2. #2
    Membre éclairé
    Homme Profil pro
    responsable adjoint service stat
    Inscrit en
    Mars 2009
    Messages
    448
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : responsable adjoint service stat
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2009
    Messages : 448
    Points : 823
    Points
    823
    Par défaut
    Pas d'autres solutions que de faire un peu de langage macro
    Voici un exemple de mise en oeuvre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
     
    data A ; do numOBS = 1 to 45000 ; output ; end ; run ;
     
    %macro VENTILE_TABLE ( TABLE ) ;
     
    /* 1. Compter le nombre d'observations dans ta table */
        data _NULL_;
            BaseId = Open("&TABLE." ,    "i") ;
            NOBS   = attrn(BaseId   , "NOBS") ;
            RC     = Close(BaseId           ) ;
            call symputx ("NB_observations" , NOBS);
        run;                                            
        %put nombre d observations : &NB_observations. ; 
     
    /* 2. Nombre de tables à construire */     
        %let NB_tables = %sysfunc( ceil ( %sysevalf( &NB_observations. / 10000 ) ) ) ;
        %put nombre de tables      : &NB_tables. ; 
     
    /* 3. Ventiler la table par paquet de 10000 */
        data %do loop = 1 %to &NB_TABLES. ;
                toto&loop. 
             %end ; ;
                set &TABLE. ;
                select  ;
                     %do loop = 1 %to &NB_TABLES.  ;
                        when ( %eval(&loop. - 1) * 10000 + 1  <= _N_ <=  %eval(&loop. ) * 10000 ) do ; 
                            numOBS = numOBS -%eval(&loop. - 1) * 10000 ;
                            output toto&loop. ; 
                            end ; 
                     %end ;  
                     otherwise ;
                     end ; 
            run ; 
     
     
     
    %mend VENTILE_TABLE ;
     
    %VENTILE_TABLE (A) ;
    Demande si tu ne comprends pas une partie du code

  3. #3
    Membre éprouvé
    Homme Profil pro
    Statisticien/développeur BI
    Inscrit en
    Janvier 2012
    Messages
    326
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Statisticien/développeur BI
    Secteur : Transports

    Informations forums :
    Inscription : Janvier 2012
    Messages : 326
    Points : 1 142
    Points
    1 142
    Par défaut
    Bonjour,

    Ci-dessous une solution sans code macro :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    DATA A; 
    do numOBS = 1 TO 45000; output; end; run;
     
    data _null_;
    set A nobs=nbreobservations;
    nbreiteration = ceil(nbreobservations/10000);
    if _n_ = 1 then do i = 1 to nbreiteration;
    	call execute ('data toto'||left(i)||';');
    	call execute ('set A (firstobs='||(i-1)*10000+1||' obs='||10000*i||');');
    	call execute ('run;');
    else stop;
    end;
    run;

  4. #4
    Membre éclairé
    Homme Profil pro
    responsable adjoint service stat
    Inscrit en
    Mars 2009
    Messages
    448
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : responsable adjoint service stat
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2009
    Messages : 448
    Points : 823
    Points
    823
    Par défaut
    OK Edward, solution possible SANS langage macro
    J'aurai du dire "pas de solution possible sans utiliser des fonctions un peu avancées de SAS", dont le call execute fait partie ;-)
    bonne journée

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 155
    Points : 37
    Points
    37
    Par défaut
    cMerci Remi pour ta réponse.
    Merci à toi aussi Edward .
    J'ai commencé par le code à Edward ,il aime pas le "else" avec ce message d'erreur:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    else stop;
               ____
               160
    ERROR 160-185: No matching IF-THEN clause.

    Merci à vous deux

  6. #6
    Membre éclairé
    Homme Profil pro
    responsable adjoint service stat
    Inscrit en
    Mars 2009
    Messages
    448
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : responsable adjoint service stat
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2009
    Messages : 448
    Points : 823
    Points
    823
    Par défaut
    Je pense que dans son code il y a une inversion entre le end et le else :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    DATA _null_;
    SET A nobs=nbreobservations;
    nbreiteration = ceil(nbreobservations/10000);
    IF _n_ = 1 then do i = 1 TO nbreiteration;
    	call execute ('data toto'||LEFT(i)||';');
    	call execute ('set A (firstobs='||(i-1)*10000+1||' obs='||10000*i||');');
    	call execute ('run;');
    end;
    else stop;
    run;

  7. #7
    Membre éclairé
    Homme Profil pro
    responsable adjoint service stat
    Inscrit en
    Mars 2009
    Messages
    448
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations professionnelles :
    Activité : responsable adjoint service stat
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2009
    Messages : 448
    Points : 823
    Points
    823
    Par défaut
    D'ailleurs la condition if then else peut être supprimée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    DATA _null_;
    SET A nobs=nbreobservations;
    nbreiteration = ceil(nbreobservations/10000);
    do i = 1 TO nbreiteration;
    	call execute ('data toto'||LEFT(i)||';');
    	call execute ('set A (firstobs='||(i-1)*10000+1||' obs='||10000*i||');');
    	call execute ('run;');
    end;
    stop;
    run;

  8. #8
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 155
    Points : 37
    Points
    37
    Par défaut
    Merci Remi

    Avec ce code elle me sort une continuité dans la valeur de la colonne NumOBS (nbreobservations) dans les tables toto1,toto2,toto3.....
    Je cherche a obtenir une incrémentation (un affichage)de 1 à 10.000 pour chaque table.Est-il possible de le faire sur le même code ?
    Pour l'instant elle me sort pour :

    TOTO1 ===> NUmOBS de 1 à 10.000
    TOTO2 ===> NUMOBS de 10.001 à 20.000 ...

    et ce que je cherche c'est avoir :

    TOTO1 ===> NUmOBS de 1 à 10.000 et
    TOTO2 ===> NUMOBS de 1 à 10.000
    TOTO3 ===> NUMOBS de 1 à 10.000 ...


    Merci à vous

  9. #9
    Membre expérimenté
    Homme Profil pro
    Développeur en SAS/ Statisticien
    Inscrit en
    Janvier 2013
    Messages
    483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur en SAS/ Statisticien
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2013
    Messages : 483
    Points : 1 552
    Points
    1 552
    Par défaut
    Bonjour,
    Je crois que la solution consiste à créer une variable compteur (cpt) pour chaque table allant de 1 à 10000.
    Puis renommer cette variable comme ceci tout en gardant la data _null_ proposée par Edward :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    %let nn=10000 ;
    data Test (drop=numobs rename=(cpt=numobs)) ;
    set A nobs=nbrobs ;
    nbreiteration= ceil(nbrobs/&nn);
    cpt+1 ;  
    if cpt=&nn+1  then do ; cpt=0 ; cpt+1 ;end ;
    run;	 
     
    DATA _null_;
    SET Test  ;
    do i = 1 TO nbreiteration;
    	call execute ('data Test'||LEFT(i)||';');
    	call execute ('set Test (firstobs='||(i-1)*&nn+1||' obs='||&nn*i||');');
    	call execute ('run;');
    end;    
    stop;
    run;
    Ward

  10. #10
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 155
    Points : 37
    Points
    37
    Par défaut
    Merci Ward pour ta réponse.
    Mais il me récupère le "nbreiteration" comme une variable en plus dans mes sorties.

  11. #11
    Membre expérimenté
    Homme Profil pro
    Développeur en SAS/ Statisticien
    Inscrit en
    Janvier 2013
    Messages
    483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur en SAS/ Statisticien
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2013
    Messages : 483
    Points : 1 552
    Points
    1 552
    Par défaut
    Pour supprimer la variable « nbreiteration » il faut ajouter (drop=nbreiteration) dans la 1ère call execute.

  12. #12
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 155
    Points : 37
    Points
    37
    Par défaut
    Bonjour Ward et merci encore pour ta réponse d'hier soir.

    J'ai appliqué le drop sur la première ligne call execute avec ' ' et sans ' ' avec ( ) et sans () dans différents endroit sur la première execute mais ça donne toujours des erreurs,il aime pas.

  13. #13
    Membre expérimenté
    Homme Profil pro
    Développeur en SAS/ Statisticien
    Inscrit en
    Janvier 2013
    Messages
    483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur en SAS/ Statisticien
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2013
    Messages : 483
    Points : 1 552
    Points
    1 552
    Par défaut
    Bonjour,
    Tu peux essayer ce code après l'ajout de DROP :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    call execute ('data Test_'||LEFT(i)|| '(drop=nbreiteration) ;' );

  14. #14
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 155
    Points : 37
    Points
    37
    Par défaut
    Un grand merci à vous Ward ,Remi,Edward vous m'avez sorti d'affaire
    ça marche très bien !!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. mettre une table dans plusieurs tables
    Par mat75019 dans le forum Access
    Réponses: 5
    Dernier message: 16/06/2006, 11h46
  2. Scinder une table en plusieurs tables
    Par hyol dans le forum Access
    Réponses: 4
    Dernier message: 22/02/2006, 14h05
  3. [SQL] Une requête dans plusieurs tables
    Par Anduriel dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 23/12/2005, 16h23
  4. Comment rechercher une chaine dans plusieurs tables ?
    Par tsing dans le forum Requêtes
    Réponses: 2
    Dernier message: 26/11/2005, 18h04
  5. Une seule table VS plusieurs tables
    Par LostControl dans le forum Requêtes
    Réponses: 1
    Dernier message: 11/08/2003, 10h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo