שלום,
הקובץ הראשוני הוא תאריכים שנמצאים באותו משתנה ולאחר שאני הופכת אותו יש לי מספר משתנים של תאריכים
אני רוצה לבנות מערך שבו מספר המשתנים יכול להשתנות (משתנים שמכילים תאריכים) מהרצה להרצה?
ובתוך המערך אני רוצה לדעת את המרווחים בין משתנה למשתנה בשביל לדעת מה המרווחים בין התאריכים והאם הם 30 יום או פחות או יותר.
איך אני יכולה לבנות את זה בצורה המיטבית?
שלום,
אפשרות אחרת היא להמנע מהשחלוף (Transpose) לגמרי ולהשתמש ב- LAG:
data ROWS;
length
Customer_ID 8
Date 8;
input customer_id date:ddmmyy10.;
format date ddmmyy10.;
datalines;
1 10/08/2020
1 25/08/2020
2 1/08/2020
2 15/08/2020
2 31/08/2020
3 12/08/2020
;
run;
proc sort data=ROWS out=ROWS1;
by customer_id date;
run;
data ROWS2(drop=_:);
set ROWS1;
by customer_id;
_p_date=lag(date);
if first.customer_id then _p_date=.;
if _p_date^=. then Diff_Dates=intck('day', _p_date, date);
else Diff_Dates=.;
run;
תודה,
חגי
שלום @Yul
אם הבנתי נכון את השאלה עשית Transpose לקובץ ובעצם כל שורה הפכה לעמודה וכך יש לך מספר לא ידוע מראש של עמודות (כי את לא יודעת מראש את מספר השורות שהיו).
בהנחה ששמות העמודות מתחילות באותה תחילית אז אפשר ליישם פתרון כזה:
data input;
do date = "01jan2020"d to "17jan2020"d;
output;
end;
run;
proc transpose data=input out=t_input;
run;
data t_input;
set t_input;
array dates (*) COL:;
do i = 2 to dim(dates);
diff = dates(i) - dates(i-1);
put diff=;
end;
run;
בהנחה שמלבד עמודת התאריכים קיימת גם עמודת זהות (מס' לקוח/מס' הזמנה וכדומה) אזי קיימת אפשרות שמספר השורות של זהות אחת יהיה שונה ממספר השורות בזהות אחרת, ומכאן נובעת גם הבקשה להגדרה דינמית של כמות האיברים במערך.
בפועל, כאשר הופכים קובץ מארוך לרחב, כמות האברים במערך יהיה אחיד ושווה למספר השורות המקסימלי שיש מבין כל הזהויות.
נניח שלזהות א' יש 3 שורות ולזהות ב' 5 שורות אזי המערך יוגדר עם 5 איברים.
בזהות א' יהיו 3 איברים עם תוכן ועוד שני איברים עם missing value.
לאור זאת, בפתרון המוצג ע"י אייל, הפעולה
diff = dates(i) - dates(i-1);
עשויה ליצור תוצאה שהיא missing value ובתנאים אחרים
(options dsoptions=note2err;)
תוצג שגיאה בלוג. לפיכך הייתי ממליץ לשנות את הקוד ל-
do i = 2 to dim(dates);
if dates(i) = . then leave; /* שורה שהוספתי */
diff = dates(i) - dates(i-1);
put diff=;
end;
שלום,
אפשרות אחרת היא להמנע מהשחלוף (Transpose) לגמרי ולהשתמש ב- LAG:
data ROWS;
length
Customer_ID 8
Date 8;
input customer_id date:ddmmyy10.;
format date ddmmyy10.;
datalines;
1 10/08/2020
1 25/08/2020
2 1/08/2020
2 15/08/2020
2 31/08/2020
3 12/08/2020
;
run;
proc sort data=ROWS out=ROWS1;
by customer_id date;
run;
data ROWS2(drop=_:);
set ROWS1;
by customer_id;
_p_date=lag(date);
if first.customer_id then _p_date=.;
if _p_date^=. then Diff_Dates=intck('day', _p_date, date);
else Diff_Dates=.;
run;
תודה,
חגי
במקום פונקציית lag ניתן להשתמש בפונקציית dif (הוכנס תיקון לאחר בדיקה)
data ROWS2;
set ROWS1;
by customer_id;
Diff_Dates = dif(date);
if first.customer_id or date=.
then Diff_Dates = .;
run;
היי,
.ואיך ניתן לעשות מערך בתוך מערך כאשר אני רוצה לשנות את שמות המשתנים
כלומר אני רוצה מערך שירוץ על מספרים שמתחילים כולם באותה אות ואז
לשנות להם שם ל
NUMREPORT1-....
?
@Yul wrote:
היי,
.ואיך ניתן לעשות מערך בתוך מערך כאשר אני רוצה לשנות את שמות המשתנים
כלומר אני רוצה מערך שירוץ על מספרים שמתחילים כולם באותה אות ואז
לשנות להם שם ל
NUMREPORT1-....
?
1) שאלה זו אינה קשורה לשאלה הקודמת ומן הדין שתפתח כשאלה חדשה.
2) לא ניתן לשנות שמות משתנים של קובץ SAS תוך כדי עיבוד של אותו הקובץ אלא בכתיבה מפורשת
של משפט RENAME
3) ניתן לאתר את שמות המשתנים הקיימים בקובץ SAS נתון תוך קריאת טבלת SASHELP.VCOLUMN,
שליפת השורות הרלוונטיות על פי LIBNAME, MEMNAME וקידומת שם שדה רצויה, ולבנות
משתנה מקרו עם משפט RENAME מתאים אשר ישמש ב STEP הבא.
לדוגמה:
data have;
retain old1-old7;
array ol {*} old1-old7;
do i=1 to dim(ol); ol(i)=i; end;
drop i;
run;
data _null_;
set sashelp.vcolumn(where=(libname='WORK' and memname='HAVE')) end=done;
length ren $100 seq $3;
retain ren;
if upcase(substr(name,1,3))='OLD' then do;
seq = compress(name,,'kd');
ren = compbl(cat(ren,strip(name),'=new',seq,' '));
end;
if done then call symput('REN',strip(ren));
run;
%put REN=&ren;
data want;
set have;
rename &ren;
run;
א - אתה צודק אבל לא מצאתי איפה פותחים נושא חדש בחיפוש מהיר
ב- אני התכוונתי לARRAY בתוך ARRAY
יול, נא תן/תני דוגמה למה הכוונה ב:
".ואיך ניתן לעשות מערך בתוך מערך כאשר אני רוצה לשנות את שמות המשתנים כלומר אני רוצה מערך שירוץ על מספרים שמתחילים כולם באותה אות ואז לשנות להם שם
- האם בשינוי שמות משתנים הכוונה ליצירת משתנים חדשים או להתייחסות לשתנים אחרים קיימים?
- לא ברור מה הצורך ומה המטרה.
יש לי קובץ שהשמות של המשתנים שלו כולם מתחילים באות - F
כלומר F1- F25
ואני רוצה שהשמות של המשתנים יהיו עם שמות בעלי משמעות לקובץ הנתונים ולכן רוצה שהשמות של המשתנים ישתנו ל
REPORT1-REPORT25
מקווה שזה יותר ברור עכשיו
שלום,
רצ"ב שתי שיטות לביצוע ההמרה.
* Sample data;
data MY_DATA(drop=i j);
length
F1-F25 8;
array fs{*} f1-f25;
do i=1 to 10;
do j=1 to dim(fs);
fs[j]=rand('UNIFORM');
end;
output;
end;
run;
/*******************
* Option 1 - macro *
*******************/
%macro rename_columns;
%let number_of_columns=25;
data MY_DATA;
set MY_DATA;
rename
%do i=1 %to &number_of_columns;
F&i = REPORT&i
%end;
;
run;
%mend;
%rename_columns;
/*********************************
* Option 2 - translation dataset *
*********************************/
* This dataset can be created using Excel file or any other method;
data TRANSLATION;
length
Old_Name
New_Name $32;
input old_name new_name;
datalines;
F1 Acura
F2 Audi
F3 BMW
F4 Buick
F5 Cadillac
F6 Chevrolet
F7 Chrysler
F8 Dodge
F9 Ford
F10 GMC
F11 Honda
F12 Hummer
F13 Hyundai
F14 Infiniti
F15 Isuzu
F16 Jaguar
F17 Jeep
F18 Kia
F19 Land_Rover
F20 Lexus
F21 Lincoln
F22 MINI
F23 Mazda
F24 Mercedes_Benz
F25 Mercury
;
run;
* Running SAS code to generate SAS code;
filename sascode temp;
data _null_;
set translation end=last;
file sascode;
if _n_=1 then do;
put "data MY_DATA;";
put "set MY_DATA;";
put "rename ";
end;
put old_name '=' new_name;
if last then do;
put ";";
put "run;";
end;
run;
* Run the generated SAS code;
%include sascode;
חגי
בקוד שהצגתי קודם השתמשתי בקידומת מקורית old (ה _F) ובקידומת חדשה NEW (ה REPORT).
אם תחליפי את הקידומות ובהתאמה קלה תוכלי לבצע את שינוי השמות.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!