1

I need to present a linear x-axis, which means that distance between timepoints needs to be time-proportional. I have done the following code:

/*Produce mean +/- SD plot with line graph*/
proc sgplot data=adpc;
vline hours /response=value group=dose stat=mean limitstat=stderr;
xaxis label='Hours post dose';
yaxis label='Mean +/- SD';
run;

This is the output: enter image description here The x-axis has the variable hours which takes the values 0,1,2,3,4,6,8,24 (hours). I think to be time-proportional, means that it should have equal range between the observations. For example, x-axis should be 0,2,4,6,8,10,12,14,16,18,20,22,24 (not sure what time-proportional means). what should i add?

Gwendoline
  • 33
  • 4
  • It depends a bit on how your raw data is structured, please show an example of your original data. You would need to use SERIES + SCATTER for your drop lines/CI but with the stat=mean it looks like you're doing calculations during the graphing process as well? In that case you may need to pre-process your data. – Reeza Jul 06 '21 at 14:49
  • i dont know how to reply with an image here.. – Gwendoline Jul 06 '21 at 15:25
  • Posting data as an image is not a good idea, text or data step are preferred. https://communities.sas.com/t5/SAS-Communities-Library/How-to-create-a-data-step-version-of-your-data-AKA-generate/ta-p/258712 – Reeza Jul 06 '21 at 15:38

3 Answers3

2

The issue here is that VLINE is a categorical graph - like a bar graph but with lines. So the X Axis is a categorical axis! The only way to get a categorical axis to be proportional is to not skip any categories.

Better would be to use series or similar, which uses a numeric axis.

Here's an example using made up data (please provide that in the future!) and a HIGHLOW to add your bars.

data adpc;
call streaminit(7);
do dose = 1,5,10,100;
    do _i = 1 to 100;
        hours = rand('Integer',1,8);
        if hours in (5,7) then hours=24;
        value = rand('Uniform')*100*log(dose+1);
        output;
    end;
end;
run;
proc means data=adpc nway;
  class dose hours;
  var value;
  output out=adpc_mean mean(value)=value stderr(value)=std;
run;

data adpc_calc;
  set adpc_mean;
  std_high = value+std;
  std_low  = value-std;
run;


proc sgplot data=adpc_calc;
  series x=hours y=value/group=dose;
  highlow x=hours high=std_high low=std_low/ lowcap=serif highcap=serif;
  xaxis values=(1,2,3,4,6,8,24);
run;

enter image description here

Joe
  • 62,789
  • 6
  • 49
  • 67
  • the thing is that i need to perform a mean +/- line graph for each dose (4 doses) over time. I wrote this: proc sgplot data=adpc; series x=hours_post_dose y=value group=dose stat=mean limitstat=stderr; xaxis label='Hours post dose'; yaxis label='Mean +/- SD'; run; but the stat=mean and limitstat=stderr does not work. – Gwendoline Jul 06 '21 at 15:24
  • wow great! But is there any other way that it automatically calculates the means and sd?? like my initial coding? – Gwendoline Jul 06 '21 at 15:35
  • Maybe it's possible using GTL, but I don't know how. The summarized plots are for categoricals for the most part. It shouldn't really cost you much time to do the extra step(s) as SAS is just doing that on the back end anyway. – Joe Jul 06 '21 at 15:38
  • I just wanted to be sure that i wouldnt make any mistakes in the manual formula, but as i can see, yours works perfect. One thing, every time i run your code, the graph changes. why is that? By the way, thanks a lot for helping me – Gwendoline Jul 06 '21 at 15:41
  • 1
    The graph shouldn't be changing, if you're running the exact code above. – Joe Jul 06 '21 at 15:53
  • you are right. maybe i pressed something wrong. out of curiosity, is there anything i could add on MY code to make this work ? – Gwendoline Jul 06 '21 at 16:01
1

Have you tried specifying the values in the XAXIS statement explicitly?

You'll need to list them all but this should give you the idea:

xaxis label='Hours post dose' values = ("0" "2" "4" "6" "8" "10" "12" ... "24");

EDIT: this more simplified version using the fake data from @Joe works well.

data adpc;
call streaminit(7);
do dose = 1,5,10,100;
    do _i = 1 to 100;
        hours = rand('Integer',1,8);
        if hours in (5,7) then hours=24;
        value = rand('Uniform')*100*log(dose+1);
        output;
    end;
end;
run;

proc sgplot data=adpc;
vline hours /response=value group=dose stat=mean limitstat=stderr;
xaxis label='Hours post dose' values = (0 to 24 by 2);
yaxis label='Mean +/- SD';
run;

Reeza
  • 20,510
  • 4
  • 21
  • 38
  • 1
    xaxis label='Hours post dose' values = ("0" "2" "4" "6" "8" "10" "12" ... "24"); that worked pretty well. thank you!!! – Gwendoline Jul 07 '21 at 13:17
0

Add the option type=time to your XAXIS statement. You will also be required to use the values= option to explicitly state the dosage values to be ticked.

Example:

proc sgplot data=have;
vline hours /response=value group=dose stat=mean limitstat=stderr;
xaxis label='Hours post dose' 
   type=time values=(0 to 4,6,8,24)  /* added to xaxis statement */
;
yaxis label='Mean +/- SD';
run;

Full example:

data have;
  call streaminit(2021);
  do patid = 1 to 500;
    dose = int( (patid-1) / (500/4) );
    do hours = 0 to 4, 6, 8, 24;
      select (dose);
        when (0) value = hours/24 * 25;
        when (1) value = hours/24 * 45;
        when (2) value = ifn (hours<6, hours/6 * 100, 100 - hours/24 * 25);
        when (3) value = ifn (hours<6, hours/6 * 250, 250);
        otherwise;
      end;

      base = value;
      jitter = rand('uniform') * hours;
      value = min(jitter * value, 250);

      output;
    end;
  end;
run;

ods html file='vline.html';

proc sgplot data=have;
vline hours /response=value group=dose stat=mean limitstat=stderr;
xaxis label='Hours post dose' type=time values=(0 to 4,6,8,24);
yaxis label='Mean +/- SD';
run;

ods html close;

Produces

enter image description here

Richard
  • 25,390
  • 3
  • 25
  • 38