According to https://community.jmp.com/t5/Discussions/Displaying-at-risk-tables-under-kaplan-meier/m-p/55338/high... , Could you please provide the method for generating a risk table underneath the KM plot? I tried to follow the script from the comment but it was closed to be solved.
dt = Current Data Table ();
minT = 0;
maxT = 25;
stepT = 1;
Summarize( lv = by( :group) );
obj = Survival(
Y( :time ),
Censor( :"reject"n ),
Grouping( :group ),
Failure Plot( 0 ),
SendToReport(
Dispatch(
{"Survival Plot"},
"1",
ScaleBox,
{Min( 0 ), Max( 25 ), Inc( 1 ), Minor Ticks( 1 )}
),
Dispatch(
{"Survival Plot"},
"time",
TextEditBox,
{Set Text( "Times(years)" )}
)
)
) << report;
obj[List Box( 2 )] << append( Table Box( String Col Box( "No at Risk | Year", lv ) ) );
Tab1 = (obj[lv[1]][Table Box( 1 )] << get);
Tab2 = (obj[lv[2]][Table Box( 1 )] << get);
For( T = minT, T <= maxT, T += stepT,
lp = Max( Loc( Matrix( Tab1 [years] ) <= T ) );
AR1 = Tab1["At Risk"][lp];
lp = Max( Loc( Matrix( Tab2 [years]) <= T ) );
AR2 = Tab2["At Risk"][lp];
obj[List Box( 2 )][Table Box( 1 )] << append( Number Col Box( Char( T ), {AR1, AR2} ) );
);
the out put showed as the attachment picture. Could you please to correct the script?
Thank you
I attempted to parametrize the code a bit further, does this do what you are looking for if you change minT, maxT, stepT, ycol, grouping and use your table
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Rats.jmp");
minT = 100;
maxT = 350;
stepT = 50;
ycol = "days";
grouping = "Group";
Summarize(dt, groups = by(Eval(grouping)));
obj = dt << Survival(
Y(Eval(ycol)),
Censor(:Censor),
Grouping(Eval(grouping)),
Show Points(1),
SendToReport(
Dispatch({"Survival Plot"}, "1", ScaleBox,
{Min(minT), Max(maxT), Inc(stepT), Minor Ticks(1)}
),
)
);
rep = Report(obj);
rep[List Box(2)] << append(tb = Table Box(String Col Box("No at Risk ("||ycol||")", groups)));
rep[List Box(2)] << Append(Spacer Box(Size(0,20)));
tabs = {};
For Each({group}, groups,
Insert Into(tabs, Eval List({rep[OutlineBox(group), Table Box(1)] << get}));
);
For(T = minT, T <= maxT, T += stepT,
ARs = {};
For Each({tab}, tabs,
lp = Max(Loc(Matrix(tab[ycol]) <= T));
Insert Into(ARS, tab["At Risk"][lp])
);
tb << append(Number Col Box(Char(T), ARs));
);
Edit: small fixes
I attempted to parametrize the code a bit further, does this do what you are looking for if you change minT, maxT, stepT, ycol, grouping and use your table
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Rats.jmp");
minT = 100;
maxT = 350;
stepT = 50;
ycol = "days";
grouping = "Group";
Summarize(dt, groups = by(Eval(grouping)));
obj = dt << Survival(
Y(Eval(ycol)),
Censor(:Censor),
Grouping(Eval(grouping)),
Show Points(1),
SendToReport(
Dispatch({"Survival Plot"}, "1", ScaleBox,
{Min(minT), Max(maxT), Inc(stepT), Minor Ticks(1)}
),
)
);
rep = Report(obj);
rep[List Box(2)] << append(tb = Table Box(String Col Box("No at Risk ("||ycol||")", groups)));
rep[List Box(2)] << Append(Spacer Box(Size(0,20)));
tabs = {};
For Each({group}, groups,
Insert Into(tabs, Eval List({rep[OutlineBox(group), Table Box(1)] << get}));
);
For(T = minT, T <= maxT, T += stepT,
ARs = {};
For Each({tab}, tabs,
lp = Max(Loc(Matrix(tab[ycol]) <= T));
Insert Into(ARS, tab["At Risk"][lp])
);
tb << append(Number Col Box(Char(T), ARs));
);
Edit: small fixes
Hi Jarmo, Thank you for your help. It worked!
Best, Theerachai
Here is also a script which can be used basically on Survivor report. It might work in most of the cases but not sure if it will as I'm not that familiar with this JMP Platform or analysis. I also modified the calculations so they might not be exactly correct
First you have to have Survivor report open
then you can run the script and it will ask for few things
Fill in those and press OK
It will then add the table to your existing report
Script below (and also attached). Use at your own risk, the calculations have not been checked
/*""" Add risk table to Survival platform
Author: jthi
Creation Date: 2024-07-31
Creation JMP Version: JMP Pro 18.0.1
Description: Based on
https://community.jmp.com/t5/Discussions/Displaying-at-risk-tables-under-kaplan-meier/m-p/305898/highlight/true#M56162
Todo:
* Show steps to user before pressing OK
* Remove modal window
* Turn into add-in / proper script
* Add instructions / title to UI
* Add utility modal
"""*/
Names Default To Here(1);
ask_steps = function({}, {Default Local},
nw = New Window("Fill in Time to Event Steps", << Type("Modal Dialog"), << Return Result,
H List Box(
Panel Box("Fill in steps",
Lineup Box(N Col(2),
Text Box("Min Time"),
neb_min = Number Edit Box(.),
Text Box("Max Time"),
neb_max = Number Edit Box(.),
Text Box("Step Time"),
neb_step = Number Edit Box(.),
Text Box("Interpolate last"),
cb_interpolate = Check Box({""}, << Set All(1))
)
),
Spacer Box(Size(20, 0)),
Panel Box("Actions",
Button Box("OK"),
Button Box("Cancel")
)
)
, << Set Window Icon("Survival")
);
If(nw["Button"] != 1,
Throw("Cancelled");
);
min_t = nw["neb_min"];
max_t = nw["neb_max"];
step_t = nw["neb_step"];
If(Any(Is Missing(min_t), Is Missing(max_t), Is Missing(step_t)),
Throw("Steps not filled in");
);
interpolate_last = N Items(nw["cb_interpolate"]);
return(Eval List({min_t, max_t, step_t, interpolate_last}));
);
add_risk_table = function({platform_ref, min_t, max_t, step_t, interpolate_last}, {Default Local},
rep = Report(platform_ref);
dt = platform_ref << Get Data Table;
ycol = ((rep << XPath("//TextBox[text()='Time to event: ']"))[1] << sib) << get text;
grouping_col = ((rep << XPath("//TextBox[text()='Grouped by ']"))[1] << sib) << get text;
Summarize(dt, groups = by(Eval(grouping_col)));
steps = min_t::max_t::step_t;
vals = steps;
For Each({group}, groups,
m_tb = rep[OutlineBox(group), Table Box(1)] << get as matrix;
times = m_tb[0, 1];
atrisk = m_tb[0, N Cols(m_tb)];
cur_steps = Step(steps, times, atrisk); // Last one isn't assumed in this
If(interpolate_last,
If(times[N Rows(times), 1] < max_t & Is Missing(cur_steps[N Cols(cur_steps)]),
cur_steps[N Cols(cur_steps)] = atrisk[N Rows(times), 1];
);
);
vals = vals |/ cur_steps;
);
pb = Panel Box("Risk Table", tb_results = Table Box(
String Col Box(Eval Insert("No at Risk (^ycol^)"), groups),
));
For(i = 1, i <= N Cols(vals), i++,
cur_vals = vals[0, i];
title = Char(Remove From(cur_vals, 1)[1]);
tb_results << Append(Number Col Box(title, cur_vals));
);
rep[List Box(2)] << Append(pb);
rep[List Box(2)] << Append(Spacer Box(Size(0, 10)));
);
cur_rep = Current Report();
If(Is Empty(cur_rep),
Throw("No reports open");
);
ob_ref = cur_rep << XPath("//OutlineBox[@helpKey='Surv']");
If(N Items(ob_ref) == 0,
Throw("No Surv platform found");
);
Try(
{min_t, max_t, step_t, interpolate_last} = ask_steps();
platform_ref = ob_ref[1] << get scriptable object;
add_risk_table(platform_ref, min_t, max_t, step_t, interpolate_last);
,
Throw("Other issues: " || char(exception_msg));
);
Write();