Join Now

Filtrering af variable

by Contributor SanderEhmsen on ‎10-23-2014 09:51 AM (528 Views)

Kære alle

Er der nogen, der kan lure, om jeg kan gøre følgende:

Jeg har et datasæt fra et spørgeskema. Jeg vil rigtig gerne have frasorteret alle rækker i mine data, der indeholder svarene '.' og 'Ved ikke'.

Umiddelbart var min tanke at vende where-statementet om i en proc sql;

Så proc sql;

select * from data where '.' not in (var1, var2, var3...) and 'Ved ikke' not in (var1, var2....);

quit;

Og endnu bedre, at not in (var1...) kunne erstattes med *.

Kan dette gøres smart? Jeg er ikke ferm til makroer, men tænker, at det desværre nok er denne vej, man er nødt til at gå?!

Mange hilsner,

Sander Ehmsen.

Comments
by SAS Employee GeorgMorsing
on ‎10-24-2014 03:26 AM

Hej Sander.


God problemstilling. Smiley Happy

Lidt problem i din opgaveformulering fordi du skriver '.' og 'Ved ikke'. Begge udsagn er i apostrof, altså kun karakterkolonner? Jeg gætter på at du mener numeriske må ikke indeholde et punktum og karakter ikke må indeholde 'Ved ikke'. Jeg er ikke sikker på at du kan løse opgaven på den må du ønsker med PROC SQL. Men med DATA Steppet vil jeg løse opgaven som vist nedenfor, hvor jeg kun har løst den for de numeriske kolonner. Men det vil være enkelt at gøre det for karakter kolonner også, det er jo bare en array mere.

Jeg har vedhæftet SAS programmet vist nedenfor.

Løser dette dit problem?

Georg

Slet Missing.jpg

by Occasional Contributor MACH
on ‎10-24-2014 04:27 AM

Jeg tænker, at en lille SQL til macro-variable finte kunne hjælpe:

** Test datasæt **;

data test;

length var1 var2 var3 var4 $ 20.;

var1='a'; var2='b'; var3='c'; var4='d'; output;

var1='a'; var2='b'; var3='c'; var4='d'; output;

var1='a'; var2='.'; var3='c'; var4='d'; output;

var1='a'; var2='b'; var3='Ved ikke'; var4='d'; output;

run;

** Find indhold i datasæt **;

proc contents data=test out=_vars_i_test noprint varnum;

run;

** Output til macro-var **;

proc sql;

select CATS('"',name,'"n in (".","Ved ikke") ') into: _dynWhere separated by " OR " from _vars_i_test;

quit;

proc sql feedback;

create table sum_project as

select *

from test

where  not (&_dynWhere)

;

quit;

by Occasional Contributor MACH
on ‎10-24-2014 04:34 AM

... og her skal det lige tilføjes, at hvis man er sikker på, at ens variable ikke indholder mellemrum m.v. (og det er min erfaring, at det gør de ganske ofte når de kommer fra f.eks. Excel) - så kan man nøjes med

select CATT(name,' in (".","Ved ikke") ') into: _dynWhere separated by " OR " from _vars_i_test;

by Contributor SanderEhmsen
on ‎10-24-2014 07:08 AM

Hej Mads og Georg

Tusind tak for jeres input.

Begge dele løser fint mit problem. Men jeg skal bruge noget tid på at forstå, hvad det præcist er, de gør.

Man kan rigtig meget i data-steppene, men fordi jeg er opflasket med EG, har jeg næstne altid brugt proc sql-steps, når jeg har skullet behandle data.

Mads' løsning giver mig mulighed for at fjerne både '.' og 'Ved ikke', som begge er værdier i min character-variabel.

Kan jeg få dig til at give nogle kommentarer på, hvad steppet i og efter dit proc contents gør, Mads?!

Tak og god weekend!

by Occasional Contributor MACH
on ‎10-24-2014 08:10 AM

Jeg kan da forsøge

PROC CONTENTS danner basalt set bare et datasæt, der indeholder alle variable i dit datasæt (oplysninger om navn, type, længde o.m.a.).

PROC SQL benytter en lille smart feature i SAS - nemlig : (Kolon). Den tager output fra din SQL sætning og putter ned i en macro-variabel.

Sætningen er i dette tilfælde lidt mere kompliceret en "normalt" - fordi jeg sikrer,at man kan have variable med f.eks. mellemrum i. Det gøres med "varnavn"n - hvor n fortæller, at der er tale om en naming literal. Og det hele er pakket ind i en CATS - fordi det er nemt Smiley Wink. Hver forekomst bliver så adskilt med " OR " og på den måde bliver der opbygget en sætning du kan bruge i din WHERE clause.

Her er funktionen i en mere simpel udgave der danner en macro-variabel der hedder names - med en comma-separeret liste med navne fra sashelp.class.

proc sql;

select name  into: names separated by "," from sashelp.class;

quit;

%put &names;

Resultat:

Alfred,Alice,Barbara,Carol,Henry,James,Jane,Janet,Jeffrey,John,Joyce,Judy,Louise,Mary,Philip,Robert,Ronald,Thomas,William

I dit tilfælde bliver det så til

"var1"n in (".","Ved ikke") OR "var2"n in (".","Ved ikke") OR "var3"n in (".","Ved ikke") OR "var4"n in (".","Ved ikke")

Mere om kolon i SAS:

http://www2.sas.com/proceedings/sugi26/p073-26.pdf

Anne Olesen har også holdt et meget fint indlæg om kolon på Klog på SAS - Indlægget er her: http://www.sas.com/offices/europe/denmark/pdf/events/blivklog/maj2013/1.Hvordan_bruger_man_kolon_i_S...

Mere om "Naming" her: SAS(R) 9.3 Language Reference: Concepts, Second Edition

M.v.h. Mads

by SAS Employee GeorgMorsing
on ‎10-24-2014 08:22 AM

Hej Sander,

Det vil være en god idé med et SAS Makro kursus. Det er altså nødvendigt, når man begynder at være så advanceret som du er på vej at være. Hvis altså nu det lille mini kursus Mads har givet os her ikke er nok. Tak Mads. Det var meget du kunne forklare på kort plads. :smileycool:

Georg

by Super Contributor
on ‎10-24-2014 04:38 PM

Avanceret makro kode er nu strengt taget ikke nødvendig for at løse dette problem. Med en do-løkke kan variablene gåes igennem, og hvis '.' eller 'Ved ikke' ikke er set efter løkken så beholdes observationen.  I mit eksempel beholder jeg heller ikke numeriske missings.

*her kører jeg på test-datasættet defineret ovenfor;

data test2;

  set test;

  array chars{*} _CHARACTER_;

  array nums{*} _NUMERIC_;

  keepobs=1;

  do k=1 to dim(chars) until (1-keepobs);

       if (chars in ('.','Ved ikke')) then keepobs=0;

  end;

  if keepobs then do k=1 to dim(nums) until (1-keepobs);

       if (nums =.) then keepobs=0;

  end;

  if keepobs;

drop k;

run;