BookmarkSubscribeRSS Feed
jcsimmo
Fluorite | Level 6

Hi there, I am trying to take a score recorded at each time interval for a subject and add columns with that score. For example I want to turn a table like this:

Study_IDMonthScore
812056
8121237
8122436
8123635
8124834
8126033
813061
813351
8131250
8132449
8133648
815047
815343
8151242
8152441
8154839

 

Into a table like this

Study_IDMonthScoreScore0Score3Score12Score24Score36Score48Score60
81205659.3736353433
812123759.3736353433
812243659.3736353433
812363559.3736353433
812483459.3736353433
812603359.3736353433
8130616151504948..
8133516151504948..
81312506151504948..
81324496151504948..
81336486151504948..
81504747434241.39.
81534347434241.39.
815124247434241.39.
815244147434241.39.
815483947434241.39.

 

I tried the following codes:


proc sort data=have;
by study_id;
run;

 

proc sql;
select max(count) into :max_count separated by ' ' from
(select count(study_ID) as count from have
group by study_ID);
quit;

 

data want;
do _n_=1 by 1 until(last.study_ID);
set have;
by study_ID;
array SCORE(*) SCORE0 SCORE3 SCORE12 SCORE24 SCORE36 SCORE48 SCORE60;
SCORE(_n_)=SCORE;

end;

do until(last.study_ID);
set have;
by study_ID;
output;
end;
run;

 

Also tried:

proc sql; (adapted from @Reeza)
select max(count) into :max_count separated by ' ' from
(select count(study_ID) as count from have
group by study_ID);
quit;

 

proc sort data=have;
by study_id month;
run;

 

proc transpose data=have out=want prefix=Score;

by study_ID;

var Score;

run;

And then did a left-join for the table. However both don't take into account months where a score wasn't recorded so I end up with a table like this

Study_IDMonthScoreScore_0Score_3Score_12Score_24Score_36Score_48Score_60
812056593736353433 
8121237593736353433 
8122436593736353433 
8123635593736353433 
8124834593736353433 
8126033593736353433 
8130616151504948..
8133516151504948..
81312506151504948..
81324496151504948..
81336486151504948..
8150474743424139. 
8153434743424139. 
81512424743424139. 
81524414743424139. 
81548394743424139. 

Where the missing months shifts the remaining scores to the left.

 

Thanks,

 

Jon

3 REPLIES 3
mkeintz
PROC Star

You can address this simply via:

  1.  Reading each id twice, first time to populate the SCORE0, SCORE3, ... SCORE60 variables (retained).  Second time to output the now complete set of values.
  2. Make an array of SCORE0 through SCORE60, indexed by the month value, making for simple use of the MONTH value (as an array index) to populate the variables.
  3. Judiciously keep a subset of SCORE0 through SCORE60.

 

data have;
  input Study_ID	Month	Score;
datalines;
812	0	56
812	12	37
812	24	36
812	36	35
812	48	34
812	60	33
813	0	61
813	3	51
813	12	50
813	24	49
813	36	48
815	0	47
815	3	43
815	12	42
815	24	41
815	48	39
run;

data want (keep=study_id month score
                score0 score3 score12 score24 score36 score48 score60);

  set have (in=firstpass)
      have (in=secondpass);
  by study_id;

  array _sc{0:60} score0-score60;
  retain score0-score60 ;

  if first.study_id then call missing(of _sc{*});
  if firstpass then _sc{month}=score;
  if secondpass;
run;

 

Note that the array _sc has a lower bound of 0 and upper bound of 60 (and names to match), which will satisfy the minimum and maximum expected value of MONTH.  Of course this creates 61 variables, most of which are not kept.  But it wonderfully simplifies the use of MONTH as an index pointing to the desired array element.

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------
r_behata
Barite | Level 11
data have;
input Study_ID Month Score;
datalines;
812 0 56
812 12 37
812 24 36
812 36 35
812 48 34
812 60 33
813 0 61
813 3 51
813 12 50
813 24 49
813 36 48
815 0 47
815 3 43
815 12 42
815 24 41
815 48 39
run;

data want(keep=study_id month score score0 score3 score12 score24 score36 
		score48 score60);
	array _score{0:60} score0-score60;
	call missing(of _score[*]);

	do _n_=1 by 1 until(last.Study_ID);
		set have;
		by Study_ID;
		_score[month]=score;
	end;

	do _n_=1 to _n_;
		set have;
		output;
	end;
run;
Ksharp
Super User
data have;
  input Study_ID	Month	Score;
datalines;
812	0	56
812	12	37
812	24	36
812	36	35
812	48	34
812	60	33
813	0	61
813	3	51
813	12	50
813	24	49
813	36	48
815	0	47
815	3	43
815	12	42
815	24	41
815	48	39
;
proc transpose data=have out=temp(drop=_name_) prefix=score_;
by study_id;
var month score;
id month;
run;
proc sql noprint;
select cats('score_',month) into :list separated by ' ' from have order by month;
quit;
data want;
retain Study_ID	Month	Score &list ;
 merge have temp;
 by study_id;
run;

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 3 replies
  • 612 views
  • 1 like
  • 4 in conversation