cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
JMP is taking Discovery online, April 16 and 18. Register today and join us for interactive sessions featuring popular presentation topics, networking, and discussions with the experts.
Choose Language Hide Translation Bar
Byron_JMP
Staff
Cycle Marker for Clinical Trial Data

 

Cycle Markers for Clinical Trial Data

Scripted solution and Add-in for taper down cycles

 

In some trials a subject receives a series of doses that are tapered from high to low. Depending on the trial, the subject may receive multiple sets of tapered doses. Identifying or labeling the cycles is currently a tedious a task if done manually, or a complex task is done programmatically.  In this blog I will describe a method for adding the cycle marker annotation to JMP tables. This version of the solution is scripted to be robust to missing dose data and duplicate doses. The scripted solution is included in a JMP add-in that provides a script-less column dialog based method for adding the column marker.

 

 

names default to here(1);

dt = Current Data Table();
//dt = Open( "cm Subset for Cycle Marker Script Testing 2.jmp" );

cnames = dt << Get Column Names( String );

cd = Column Dialog(
	colid = ColList( "Unique Subject ID", max Col( 1 ) ),
	colcmd = ColList( "CM Dose", max Col( 1 ) ),
	colseq = ColList( "CM Dose Sequence", max Col( 1 ) ),
	Text Box(
		"Note: Data will be sorted by USUBJID and CMSEQ. 
		       A Cycle Marker column will be added to the end of the data table."
	)
);


Eval( cd[1] ); 
Eval( cd[2] );
Eval( cd[3] );
Show( colid, colcmd, colseq );
cols = Expr( columns() );
subs = Expr(
	subset( all rows, private )
	//subset( all rows )
);
Insert Into( cols, colid[1] );
Insert Into( cols, colcmd[1] );
Insert Into( cols, colseq[1] );
Insert Into( subs, Eval Expr( cols ) );
Show( subs );
dt ss = subs;  

dt ss so = dtss << Sort(
	By( colid[1], colseq[1] ),
	Order( Ascending, Ascending ), 
	Output Table( "Sorted cm" ),private
	//Output Table( "Sorted cm" )
);
Close( dtss, nosave );	//don't need dtss anymore

//Technically we don't know the actual names of the columns yet
Eval Expr( colid[1] ) << set name( "USUBJID" );
Eval Expr( colcmd[1] ) << set name( "CMDOSE" );
Eval Expr( colseq[1] ) << set name( "CMSEQ" );

checkunique = Expr(
	dtssso << New Column( "UniquieCheck", formula( :USUBJID || " " || Char( :CMSEQ ) ) );
	dtssso << New Column( "UC_Count", formula( Col Number( :Name( "UniquieCheck" ), :Name( "UniquieCheck" ) ) ) );
);

makecm = Expr(
	dtssso << New Column( "Cycle Marker",
		Numeric,
		"Continuous",
		Format( "Best", 12 ),
		Formula(
			If( Row() == 1,
				1,
				If( :USUBJID != Lag( :USUBJID, 1 ),
					1,
					If( Is Missing( :CMDOSE ) == 1,
						Lag( :Cycle Marker, 1 ),
						If( :CMDOSE <= Lag( :CMDOSE, 1 ) | Is Missing( Lag( :CMDOSE, 1 ) == 1 ),
							Lag( :Cycle Marker, 1 ),
							Lag( :Cycle Marker, 1 ) + 1
						)
					)
				)
			)
		),
		Set Selected,
		Set Display Width( 61 )
	)
);
checkunique;

update cm with cycle marker=expr(dt <<
Update(
	With( dtssso ),
	Match Columns( colid[1] = :USUBJID, colseq[1] = :CMSEQ ),
	Add Columns from Update Table( :Cycle Marker )
););

If( Col Maximum( dtssso:UC_Count ) > 1,
	error=New Window( "ERROR", Text Box( "Duplicated data detected across uniquie subject ID and CM sequence" ),
	buttonbox("Acknowledge", error<<closewindow()) ),
	makecm;update cm with cycle marker;
);
close(dtssso, nosave);




//Byron Wingerd 200705


 

 

If( Row() == 1,
	1,
	If( :USUBJID != Lag( :USUBJID, 1 ),
		1,
		If( Is Missing( :CMDOSE ) == 1,
			Lag( :Cycle Marker, 1 ),
			If( :CMDOSE <= Lag( :CMDOSE, 1 ) | Is Missing( Lag( :CMDOSE, 1 ) == 1 ),
				Lag( :Cycle Marker, 1 ),
				Lag( :Cycle Marker, 1 ) + 1
			)
		)
	)
)  

 

Last Modified: Jul 10, 2020 10:57 AM