2015-12-10 1 views
0

Le code suivant, créé à l'aide de la tâche Statistiques récapitulatives de SAS Enterprise Guide, trouve la valeur minimale de chaque colonne d'une table.SAS Deuxième valeur la plus petite

Comment puis-je trouver la deuxième plus petite valeur? J'ai essayé de remplacer MIN par SMALLEST (2) mais cela ne fonctionne pas.

Merci.

TITLE; 
TITLE1 "Summary Statistics"; 
TITLE2 "Results"; 
FOOTNOTE; 
FOOTNOTE1 "Generated by the SAS System (&_SASSERVERNAME, &SYSSCPL) on 
%TRIM (%QSYSFUNC(DATE(), NLDATE20.)) at 
%TRIM(%SYSFUNC(TIME(), TIMEAMPM12.))"; 
PROC MEANS DATA=WORK.SORTTempTableSorted 
NOPRINT 
CHARTYPE 

    MIN NONOBS ; 
VAR A B C; 

OUTPUT OUT=WORK.MEANSummaryStats(LABEL="Summary Statistics for 
WORK.QUERY_FOR_TRNSTRANSPOSEDPD__0001") 

    MIN()= 

/AUTONAME AUTOLABEL INHERIT 
; 

RUN;

Répondre

0

Je ne pense pas qu'il existe un moyen d'accomplir cela au sein des moyens proc. Il existe des moyens d'utiliser une variété d'autres procs. La procédure Univariée met en évidence une méthode utilisant les observations extrêmes.

https://support.sas.com/documentation/cdl/en/procstat/63104/HTML/default/viewer.htm#procstat_univariate_sect058.htm

title 'Extreme Blood Pressure Observations'; 
ods select ExtremeObs; 
proc univariate data=BPressure; 
    var Systolic Diastolic; 
    id PatientID; 
run; 

proc print data=ExtremeObs; 
run; 
0

Je suppose que vous êtes intéressé par toutes les colonnes numériques. Si la variable de macro IFLIST a une longueur supérieure à 64 Ko en raison du nombre de variables numériques et de la longueur de leurs noms, ce code échouera. Cela devrait fonctionner pour tous les ensembles de données raisonnablement étroits.

CODE NON TESTÉ

Nous obtenons une liste des variables dans votre ensemble de données. Nous utilisons cette liste pour créer des instructions et des expressions. Nous utilisons cette liste pour créer des instructions et des expressions. IFLIST est un bloc d'instructions pour stocker la valeur minimale de fieldname dans fieldname_1 et la deuxième plus faible dans fieldname_2. Si la comparaison est LT, alors nous gardons des valeurs distinctes, pas nécessairement les statistiques d'ordre. Si la comparaison est LE et qu'il y a plusieurs observations avec la valeur minimum, fieldname_1 et fieldname_2 seront égaux entre eux. Je suppose que vous voulez des valeurs distinctes.

MAXLIST est une expression qui résoudra à la plus grande valeur numérique dans l'ensemble de données :)

MINLIST et MINLIST2 sont créés pour être utilisés et RETENIR GARDEZ déclarations.

PROC SQL STIMER NOPRINT EXEC ; 
    SELECT 'IF ' || name || ' LT ' || name '_1 THEN DO;' || 
        name || '_2=' || name || '_1;' || 
        name || '_1=' || name || ';END;ELSE IF ' || 
        name || ' LT ' || name || '_2 THEN ' || 
        name || '_2=' || name, 
     'MAX(' || name || ')', 
     name || '_1', 
     name || '_2' 
    INTO :iflist SEPARATED BY '; ', 
     :maxlist SEPARATED BY '<>' 
     :minlist SEPARATED BY ' ', 
     :min2list SEPARATED BY ' ' 
    FROM md 
    WHERE type EQ 1 
    ; 

Maintenant, nous obtenons la plus grande valeur numérique de l'ensemble de données:

SELECT &maxlist 
    INTO :maxval 
    FROM SORTTempTableSorted 
    ; 

QUIT ; 

Maintenant, nous faisons le travail. L'option END met "eof" à 1 sur la dernière observation, qui est la seule fois où nous voulons écrire un enregistrement dans l'ensemble de données de sortie.

DATA min2 ; 
    SET SORTTempTableSorted END=eof; 
    RETAIN &minlist &min2list &maxval; 
    KEEP &minlist &min2list ; 
    &iflist ; 
    IF eof THEN 
    OUTPUT ; 
RUN ; 
0

Une solution étape de données qui doivent travailler pour un certain nombre de colonnes sans jamais en cours d'exécution dans les limites macro:

proc sql noprint; 
    select count(*) into :NUM_COUNT from dictionary.columns 
    where LIBNAME='SASHELP' and MEMNAME = 'CLASS' and TYPE = 'num'; 
quit; 

data class_min2; 
    do until(eof); 
    set sashelp.class end = eof; 
    array min2[&NUM_COUNT,2] _temporary_; 
    array nums[*] _numeric_; 
    do _n_ = 1 to &NUM_COUNT; 
     min2[_n_,1] = min(min2[_n_,1],nums[_n_]); 
     if min2[_n_,1] < nums[_n_] then min2[_n_,2] = min(nums[_n_],min2[_n_,2]); 
    end; 
    end; 
    do _iorc_ = 1 to 2; 
    do _n_ = 1 to &NUM_COUNT; 
     nums[_n_] = min2[_n_,_iorc_]; 
    end; 
    output; 
    end; 
    keep _NUMERIC_; 
run; 

Cette sortie les deux valeurs les plus basses distinctes de chaque variable numérique, sans transposer les données de la même manière que le fait proc univariate. Vous pouvez facilement autoriser des valeurs minimales en double avec un peu de peaufinage.

1

Utilisation de la table ExtremeValue de PROC UNIVARIATE.

ods select none; 
ods output ExtremeValues=ExtremeValues(where=(loworder=2) drop=high:); 
proc univariate data=sashelp.class NEXTRVAL=2; 
    run; 
ods select all; 
proc print; 
    run; 

enter image description here

0

trier les valeurs dans l'ordre croissant. Supprimez la première valeur. Ce serait la valeur minimale. Maintenant, la valeur restante à la première position est votre deuxième minimum.