¿Tabla de riesgos del gráfico KM en JMP?Según https://community.jmp.com/t5/Discussions/Displaying-at-risk-tables-under-kaplan-meier/mp/55338/highlight/true#M31302 , ¿podría proporcionar el método para generar un riesgo? ¿Tabla debajo del gráfico KM? Intenté seguir el guión del comentario pero estaba cerrado por resolver.
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} ) );
);La salida se muestra como la imagen adjunta. ¿Podrías corregir el guión?
Gracias
Exploración y visualización de datosRe: ¿Tabla de riesgos del trazado KM en JMP?Intenté parametrizar el código un poco más. ¿Esto hace lo que estás buscando si cambias minT, maxT, stepT, ycol, agrupa y usas tu tabla?
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));
);
Editar: pequeñas correcciones
Re: ¿Tabla de riesgos del trazado KM en JMP?Hola Jarmo, gracias por tu ayuda. ¡Funcionó!
Mejor, Theerachai
Re: ¿Tabla de riesgos del trazado KM en JMP?Aquí también hay un script que se puede utilizar básicamente en el informe Survivor. Puede que funcione en la mayoría de los casos, pero no estoy seguro de que funcione, ya que no estoy muy familiarizado con esta plataforma JMP ni con su análisis. También modifiqué los cálculos para que pudieran no ser exactamente correctos.
Primero tienes que tener abierto el Informe de Superviviente.

Luego puedes ejecutar el script y te pedirá algunas cosas.

Rellénelos y presione OK

Luego agregará la tabla a su informe existente.

Guión a continuación (y también adjunto). Úselo bajo su propia responsabilidad, los cálculos no han sido verificados.
Ver más...
/*""" 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();
Re: ¿Tabla de riesgos del gráfico KM en JMP?¡Gracias por este script! Me gusta mucho. Cuando genero varias curvas de supervivencia a la vez utilizando la configuración que se muestra a continuación (se especifican "Agrupamiento" y "Por"), la tabla de riesgo solo se agrega al primer gráfico. ¿Hay alguna manera de agregarla a todos?

Re: ¿Tabla de riesgos del gráfico KM en JMP?Debería ser posible, pero se requieren modificaciones en el script. Puedes probar si esta versión te funciona:
Ver más...
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_refs = cur_rep << XPath("//OutlineBox[@helpKey='Surv']");
If(N Items(ob_refs) == 0,
Throw("No Surv platform found");
);
Try(
{min_t, max_t, step_t, interpolate_last} = ask_steps();
For Each({ob_ref}, ob_refs,
platform_ref = ob_ref << get scriptable object;
add_risk_table(platform_ref, min_t, max_t, step_t, interpolate_last);
);
,
Throw("Other issues: " || char(exception_msg));
);
Write();
Solo hice unos pocos cambios al final del script, básicamente agregué uno para cada bucle (y cambié el nombre de una variable).
Re: ¿Tabla de riesgos del gráfico KM en JMP?¡Gracias por la respuesta rápida! ¿Pero me aparece este mensaje?

Re: ¿Tabla de riesgos del gráfico KM en JMP?Falta una s en la línea 100

Edité mi publicación anterior para solucionar el problema.
Re: ¿Tabla de riesgos del gráfico KM en JMP?¡Gracias de nuevo! ¡Ahora funciona!
Para controlar la calidad de la salida, simplemente volví a crear una figura de referencia (ver más abajo JMP vs. referencia) y noté algunos detalles. Comenzando desde la izquierda, en el momento = 0, el número en riesgo, 40, es correcto, sin embargo, los puntos de tiempo posteriores se inflan en 1. La excepción es cuando el número verdadero es cero, que el script enumera con precisión. Por último, hay un 1 en el último punto de tiempo, que no debería estar allí. Podría solucionar esto en Excel, ¡pero sería fantástico si hubiera una solución mediante scripts!

Re: ¿Tabla de riesgos del gráfico KM en JMP?No estoy seguro de qué cálculo es incorrecto. Si está en mi script, lo más probable es que puedas corregirlo en algún lugar aquí

Necesitaría un conjunto de datos de ejemplo con respuestas correctas para saber cuáles deberían ser los resultados (aunque la opción de interpolación en mi script no parece funcionar correctamente).
Re: ¿Tabla de riesgos del gráfico KM en JMP?Siguiendo con el número de riesgo inflado. Usando tu script (¡gracias!) en el conjunto de datos de cáncer de pulmón de VP, obtengo un número de riesgo adicional de 400 para el grupo estándar y 200, 400, 600 y 800 para el grupo de prueba.

Al observar la tabla de datos, los valores con el punto de tiempo exacto (200 para el estándar, primera fila rosa) muestran el número de riesgo correcto; sin embargo, cuando no hay una coincidencia exacta, como 400, 600 y 800, el script actual trae el número anterior al punto de tiempo especificado. Sería fantástico si los scripts pudieran solucionar estos casos.


Re: ¿Tabla de riesgos del gráfico KM en JMP?¿Qué debería mostrar si no es el valor anterior?