LesezeichenAbonnierenRSS-Feed abonnieren
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Dvdscot
Obsidian | Level 7

Hallo,

 

ich habe einen Datensatz mit über 250 Datumswerten, dazu noch jedes Datum doppelt. Es werden verglichen ein Commit Datum und ein Visit Datum. Bei nur ein paar Spalten kein Problem und auch dies könnte man manuell machen. Gibt es einen Weg dies zu vereinfachen, zu automatisieren? Ich dachte an ein Makro, ein Array oder Do Loop.

 

Diese beiden werden miteinander verglichen, ihr seht jetzt die ersten 8 von 254:

commitdate_kw1_a1_kw1_aisvisitdt_kw1_A1_KW1_AIS
commitdate_kw1_a1_kw1_jiavisitdt_kw1_A1_KW1_JIA
commitdate_kw1_a1_kw1_kollvisitdt_kw1_A1_KW1_KOLL
commitdate_kw1_a1_kw1_psavisitdt_kw1_A1_KW1_PSA
commitdate_kw1_a1_kw1_ravisitdt_kw1_A1_KW1_RA
commitdate_kw1_a1_kw1_slevisitdt_kw1_A1_KW1_SLE
commitdate_kw1_a1_kw1_spavisitdt_kw1_A1_KW1_SPA
commitdate_kw1_a1_kw1_vasvisitdt_kw1_A1_KW1_VAS

 

Hier ist der Name allerdings abgeschnitten, da werde ich den zweiten erst angleichen:

commitdate_pp1_pkind10_pp1_ausga

visitdt_pp1_PKind10_PP1_Ausgang

 

Ich dachte man könnte es so machen:

If commitdate_XXX > visitdt_XXX

 

und XXX sind dann alle Endungen. Rauskommen soll dann eine dritte Datumsvariable (und die dann eben 250 mal, finaldate_XXX), falls es Unterschiede gibt, dann Visit, ansonsten Commit.

 

Wie funktioniert sowas am besten? Danke.

1 AKZEPTIERTE LÖSUNG

Akzeptierte Lösungen
PaigeMiller
Diamond | Level 26

That didn't work however, Vergleich1 to Vergleich254 are completely empty.

 

Use 

 

array vergleich $ 16 vergleich1-vergleich254;

The $ tells SAS that the array will contain character variables and the 16 indicates the maximum length of these character variables.

--
Paige Miller

Lösung in ursprünglichem Beitrag anzeigen

9 ANTWORTEN 9
PaigeMiller
Diamond | Level 26

ARRAY is definitely the tool here. I give an example, as I don't know all of your variable names, I made some up

 

data want;
    set have;
    array commitdate commitdate1-commitdate200;
    array visitdate visitdate1-visitdate200;
    do i=1 to dim(commitdate);
         if commitdate(i)>visitdate(i) then do;
         ... some action ...
         end;
    end;
run;

 

 

--
Paige Miller
Dvdscot
Obsidian | Level 7
Thanks, instead of 1 - 200 I write all 250 variable names in the correct order and SAS knows which to compare?
PaigeMiller
Diamond | Level 26

@Dvdscot  schrieb:
Thanks, instead of 1 - 200 I write all 250 variable names in the correct order and SAS knows which to compare?

If your variable names don't follow a pattern, like commitdate1 commitdate2 commitdate3 ... comittdate250 then yes, you need a list of all variables. 

 

If they all begin with commitdate and after that the variable name has a suffix of other text but not consecutive numbers, and the visitdate variable has the same suffix, there are probably macro variable tricks that can be performed so that you don't have to type all the variables yourself. Let me know if you need something like that.

--
Paige Miller
Dvdscot
Obsidian | Level 7
data Datum_im_Vergleich2;
    set Datumswerte_sort;
    array commitdate {254} 

commitdate_kw1_a1_kw1_ais
commitdate_kw1_a1_kw1_jia
commitdate_kw1_a1_kw1_koll
commitdate_kw1_a1_kw1_psa
commitdate_kw1_a1_kw1_ra
commitdate_kw1_a1_kw1_sle
commitdate_kw1_a1_kw1_spa
commitdate_kw1_a1_kw1_vas
commitdate_kw1_a1_kw1th
...

;

    array visitdate {254} 

visitdt_kw1_A1_KW1_AIS
visitdt_kw1_A1_KW1_JIA
visitdt_kw1_A1_KW1_KOLL
visitdt_kw1_A1_KW1_PSA
visitdt_kw1_A1_KW1_RA
visitdt_kw1_A1_KW1_SLE
visitdt_kw1_A1_KW1_SPA
visitdt_kw1_A1_KW1_VAS
visitdt_kw1_A1_KW1TH
...

;

	array Vergleich {254} Vergleich1 - Vergleich254;

    DO i=1 TO dim(commitdate);
        IF commitdate(i) NE . AND visitdate(i) NE . then do;
			IF commitdate(i) < visitdate(i) THEN Vergleich(i) = "Visit größer";
			ELSE IF commitdate(i) > visitdate(i) THEN Vergleich(i) = "Visit kleiner";
			ELSE Vergleich(i) = "gleich";
		END;
	ELSE Vergleich(i) = "";
	END;
run;

That didn't work however, Vergleich1 to Vergleich254 are completely empty.

 

But I have these two for example which gave this result when I did it manually: 

2021-04-19 2021-03-30 Visit kleiner

PaigeMiller
Diamond | Level 26

That didn't work however, Vergleich1 to Vergleich254 are completely empty.

 

Use 

 

array vergleich $ 16 vergleich1-vergleich254;

The $ tells SAS that the array will contain character variables and the 16 indicates the maximum length of these character variables.

--
Paige Miller
Dvdscot
Obsidian | Level 7

I did it like that now:

DATA Datum_im_Vergleich2;
    set Datum_gleich;
    array commitdate {254} 

commitdate_kw1_a1_kw1_ais
commitdate_kw1_a1_kw1_jia
commitdate_kw1_a1_kw1_koll
commitdate_kw1_a1_kw1_psa
commitdate_kw1_a1_kw1_ra
commitdate_kw1_a1_kw1_sle
commitdate_kw1_a1_kw1_spa
commitdate_kw1_a1_kw1_vas
commitdate_kw1_a1_kw1th
...
commitdate_ssv_a_ss_vorher
;

    array visitdate {254} 

visitdt_kw1_A1_KW1_AIS
visitdt_kw1_A1_KW1_JIA
visitdt_kw1_A1_KW1_KOLL
visitdt_kw1_A1_KW1_PSA
visitdt_kw1_A1_KW1_RA
visitdt_kw1_A1_KW1_SLE
visitdt_kw1_A1_KW1_SPA
visitdt_kw1_A1_KW1_VAS
visitdt_kw1_A1_KW1TH
...
visitdt_ssv_A_SS_vorher
;

	array Vergleich $ 16 {254}

vergleich_kw1_a1_kw1_ais
vergleich_kw1_a1_kw1_jia
vergleich_kw1_a1_kw1_koll
vergleich_kw1_a1_kw1_psa
vergleich_kw1_a1_kw1_ra
vergleich_kw1_a1_kw1_sle
vergleich_kw1_a1_kw1_spa
vergleich_kw1_a1_kw1_vas
vergleich_kw1_a1_kw1th
...
vergleich_ssv_a_ss_vorher

;

    DO i=1 TO dim(commitdate);
        IF commitdate(i) NE . AND visitdate(i) NE . then do;
			IF commitdate(i) < visitdate(i) THEN Vergleich(i) = "Visit größer";
			ELSE IF commitdate(i) > visitdate(i) THEN Vergleich(i) = "Visit kleiner";
			ELSE Vergleich(i) = "gleich";
		END;
	ELSE Vergleich(i) = "";
	END;
run;

But SAS complains where the char is declared, I have to read more about how to define arrays.

 

544 array Vergleich $ 16 {254}
_
Das SAS System

22
76
ERROR 22-322: Syntaxfehler, erwartet wird eines der folgenden: ein Name, _ALL_, _CHARACTER_, _CHAR_, _NUMERIC_.

ERROR 76-322: Syntax error, statement will be ignored.

 

Dvdscot
Obsidian | Level 7
I just removed the {254} and it worked, great, thanks!
andreas_lds
Jade | Level 19

Wir brauchen Daten in nutzbarer Form, um (besser) zu verstehen, was genau vorhanden ist und was passieren soll.

Zuerst müssen die 250 neuen Variablen definiert werden, dann für die drei Gruppen je ein Array definieren. Abhängig von der Reihenfolge in der die Variablen im Dataset sind, könnte etwas wie commitdate_kw1_a1_kw1_ais -- commitdate_pp1_pkind10_pp1_ausgang funktionieren, dafür müssen die commitdate-Variablen aber ohne Unterbrechung im Dataset stehen und auch in gleicher Reihenfolge, wie die visidt-Variablen. Vielleicht besser: je eine Liste der Variablen in eine Makro-Variable schreiben und die dann in der Array-Anweisung verwenden:

 

Code ist nicht getestet!

proc sql noprint;
  select Name 
    into :commit separated by ' '
    from sashelp.vcolumn
      where libname = 'WORK' and memname = 'HAVE'
  ;
quit;

data want;
  set have;
  
  array commit &commit.;
...
run;

 

PaigeMiller
Diamond | Level 26

@andreas_lds  schrieb:

Wir brauchen Daten in nutzbarer Form, um (besser) zu verstehen, was genau vorhanden ist und was passieren soll.

Zuerst müssen die 250 neuen Variablen definiert werden, dann für die drei Gruppen je ein Array definieren. Abhängig von der Reihenfolge in der die Variablen im Dataset sind, könnte etwas wie commitdate_kw1_a1_kw1_ais -- commitdate_pp1_pkind10_pp1_ausgang funktionieren, dafür müssen die commitdate-Variablen aber ohne Unterbrechung im Dataset stehen und auch in gleicher Reihenfolge, wie die visidt-Variablen. Vielleicht besser: je eine Liste der Variablen in eine Makro-Variable schreiben und die dann in der Array-Anweisung verwenden:

 

Code ist nicht getestet!

proc sql noprint;
  select Name 
    into :commit separated by ' '
    from sashelp.vcolumn
      where libname = 'WORK' and memname = 'HAVE'
  ;
quit;

data want;
  set have;
  
  array commit &commit.;
...
run;

 


CAUTION: this produces a macro variable where the variables names are in alphabetical order. This may or may not be useful.

 

Also, I think you need:

 

proc sql noprint;
  select Name 
    into :commit separated by ' '
    from sashelp.vcolumn
      where libname = 'WORK' and memname = 'HAVE' and lowcase(name) eqt 'commit';
  ;
  select Name 
    into :visit separated by ' '
    from sashelp.vcolumn
      where libname = 'WORK' and memname = 'HAVE' and lowcase(name) eqt 'visit';
  ;
quit;
--
Paige Miller