/* Create a file to retain unqiue IDs only */

data idfile; set rawdata;

    proc sort nodupkey; by userid; run;

/* Create a file to make each subject carries 5 rows (items)

/* and assigfn a faked ID to each row. The faked ID is just the ascending order (1-5) */

data idonly; set idfile;

    array XX(5) X1-X5;

        do fid=1 to 5;

        x=xx[fid];

        output;

    end;

    drop x1-x5 x itemid rawscore;

    proc sort; by fid; run;

/* import the raw data and sort them for later merger */

data score; set rawdata;

    proc sort; by userid itemid; run;

/* import a file listing the faked ID and all item IDs, including those that no one answered */

data item; set formitem;

    proc sort; by fid; run;

/* merge the ID file and item file so that every subject carries 5 items regardless of missing data */

data iditem; merge idonly item; by fid;

    proc sort; by userid itemid; run;

/* merge the raw data and the iditem file, and now even missing values are showed up. */

/* FID can be used to check whether every subject has 5 items */

data realdata; merge score iditem; by userid itemid; run;

    proc sort; by userid itemid; run;

/* transpose the data to make one subject per row */

data transpose; set realdata; by userid itemid;

    length i1-i5 $8;

    array scores s1-s5;

    array inames $ i1-i5;

        retain s1-s5 i1-i5 n;

        if first.userid then n = 1;

        scores(n) = rawscore;

        inames(n) = itemid;

        n = n+1;

        if last.userid then output;

run;