cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
  • JMP will suspend normal business operations for our Winter Holiday beginning on Wednesday, Dec. 24, 2025, at 5:00 p.m. ET (2:00 p.m. ET for JMP Accounts Receivable).
    Regular business hours will resume at 9:00 a.m. EST on Friday, Jan. 2, 2026.
  • We’re retiring the File Exchange at the end of this year. The JMP Marketplace is now your destination for add-ins and extensions.

Discussions

Solve problems, and share tips and tricks with other JMP users.
%3CLINGO-SUB%20id%3D%22lingo-sub-33664%22%20slang%3D%22en-US%22%20mode%3D%22NONE%22%3E%E3%82%B3%E3%83%83%E3%82%AF%E3%82%B9%E3%83%A2%E3%83%87%E3%83%AB%E3%81%AE%E4%B8%80%E8%87%B4%E5%BA%A6%EF%BC%88C%E3%82%A4%E3%83%B3%E3%83%87%E3%83%83%E3%82%AF%E3%82%B9%EF%BC%89%E3%81%AE%E8%A8%88%E7%AE%97%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-33664%22%20slang%3D%22en-US%22%20mode%3D%22NONE%22%3E%3CP%3E%E7%A7%81%E3%81%AFcox%E3%83%A2%E3%83%87%E3%83%AB%E3%81%AEJMP%2010%E3%81%A7%E4%B8%80%E8%87%B4%E6%8C%87%E6%95%B0%E3%82%92%E8%A8%88%E7%AE%97%E3%81%97%E3%82%88%E3%81%86%E3%81%A8%E3%81%97%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82%26nbsp%3B%E7%A7%81%E3%81%AFSAS%E3%81%AE%E3%81%93%E3%81%AE%E8%AB%96%E6%96%87%E3%82%92%E8%A6%8B%E3%81%A4%E3%81%91%E3%81%BE%E3%81%97%E3%81%9F%EF%BC%9A%3C%2FP%3E%0A%3CP%3E%3CA%20href%3D%22http%3A%2F%2Fsupport.sas.com%2Fresources%2Fpapers%2Fproceedings09%2F236-2009.pdf%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3Ehttp%3A%2F%2Fsupport.sas.com%2Fresources%2Fpapers%2Fproceedings09%2F236-2009.pdf%3C%2FA%3E%3C%2FP%3E%0A%3CP%3E%E3%81%97%E3%81%8B%E3%81%97%E3%80%81%E3%81%9D%E3%82%8C%E3%81%8C%E4%BD%95%E3%82%92%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E3%81%AE%E3%81%8B%E3%82%92%E3%82%88%E3%81%8F%E7%90%86%E8%A7%A3%E3%81%97%E3%81%A6%E3%81%84%E3%81%BE%E3%81%9B%E3%82%93%E3%80%82%26nbsp%3B%20%E4%BB%BB%E6%84%8F%E3%81%AE%E5%8A%A9%E3%81%91%E3%81%AF%E5%A4%A7%E6%AD%93%E8%BF%8E%E3%81%A7%E3%81%99%E3%80%82%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%3Eproc%20sql%3B%0A%20create%20table%20allset%20as%0A%20select%20idn_j%2C%20y_j%2C%20x_j%2C%20idn%20as%20idn_i%2C%20surv%20as%20y_i%2C%20combdays%20as%20x_i%0A%20from%20evtset%2C%20obs%0A%20where%20idn_j%26lt%3B%26gt%3Bidn%3B%0Aquit%3B%0Adata%20concord%3B%0A%20set%20allset%3B%0A%20if%20(x_i%26lt%3Bx_j%20and%20y_i%26gt%3By_j)%20or%20(x_i%26gt%3Bx_j%20and%20y_i%26lt%3By_j)%20then%20concord%3D1%3B%0A%20else%20concord%3D0%3B%0Arun%3B%20%0A%0Adata%20_null_%3B%0Aset%20concord%20end%3Deof%3B%0Aretain%20nch%20ndh%3B%0Aif%20_N_%3D1%20then%20do%3B%0Anch%3D0%3B%0Andh%3D0%3B%0Aend%3B%0Aif%20concord%3D1%20then%20nch%2B1%3B%0Aif%20concord%3D0%20then%20ndh%2B1%3B%0Aif%20eof%3D1%20then%20do%3B%0A%20call%20symput('ch'%2Ctrim(left(nch)))%3B%0A%20call%20symput('dh'%2Ctrim(left(ndh)))%3B%0A%20call%20symput('uspairs'%2Ctrim(left(_n_)))%3B%0A%20end%3B%20%0Arun%3B%0Adata%20_null_%3B%0Aset%20sample%20end%3Deof%3B%0Aif%20eof%3D1%20then%20call%20symput('totobs'%2Ctrim(left(_n_)))%3B%0Arun%3B%0A%25put%20%26amp%3Bch%20%26amp%3Bdh%20%26amp%3Buspairs%20%26amp%3Btotobs%3B%0Adata%20calculat%3B%0Ach%3Dinput(%22%26amp%3Bch%22%2C12.0)%3B%0Adh%3Dinput(%22%26amp%3Bdh%22%2C12.0)%3B%0Auspairs%3Dinput(%22%26amp%3Buspairs%22%2C12.0)%3B%0Atotobs%3Dinput(%22%26amp%3Btotobs%22%2C10.0)%3B%0Apc%3Dch%2F(totobs*(totobs-1))%3B%0Apd%3Ddh%2F(totobs*(totobs-1))%3B%0Ac_hat%3Dpc%2F(pc%2Bpd)%3B%0A%0Aw%3D(2*1.96**2)%2F(totobs*(pc%2Bpd))%3B%0Alow_ci_w%3D((w%2B2*c_hat)%2F(2*(1%2Bw)))-(sqrt((w**2%2B4*w*c_hat*(1-%0Ac_hat))%2F(2*(1%2Bw))))%3B%0Aupper_ci_w%3D((w%2B2*c_hat)%2F(2*(1%2Bw)))%2B(sqrt((w**2%2B4*w*c_hat*(1-%0Ac_hat))%2F(2*(1%2Bw))))%3B%0Arun%3B%20%3C%2FPRE%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-33722%22%20slang%3D%22en-US%22%20mode%3D%22NONE%22%3E%E3%82%B3%E3%83%83%E3%82%AF%E3%82%B9%E3%83%A2%E3%83%87%E3%83%AB%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E4%B8%80%E8%87%B4%EF%BC%88C-%E3%82%A4%E3%83%B3%E3%83%87%E3%83%83%E3%82%AF%E3%82%B9%EF%BC%89%E3%81%AE%E5%86%8D%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-33722%22%20slang%3D%22en-US%22%20mode%3D%22NONE%22%3E%3CP%3E%E3%81%93%E3%82%8C%E3%81%8C%E7%A7%81%E3%81%AESAS%E3%82%B3%E3%83%BC%E3%83%89%E3%83%AC%E3%83%93%E3%83%A5%E3%83%BC%E3%81%A7%E3%81%99%E3%80%82%3C%2FP%3E%0A%3CPRE%3E%3CCODE%20class%3D%22%20language-jsl%22%3E%2F%2FThis%20step%20does%20a%20cartesian%20join%20of%20the%20evtset%20and%20obs%20data%20tables%2C%0A%2F%2F%20but%20eliminates%20any%20rows%20where%20the%20column%20idn_j%3Didn%0A%2F%2F%20To%20do%20this%20in%20JMP%20would%20be%20a%202%20step%20process.%20%20Use%20%0A%2F%2F%20%20Tables%3D%3D%26gt%3BJoin%0A%2F%2F%20and%20specify%20to%20perform%20a%20Cartesian%20Join%2C%20then%20find%20all%20rows%20in%20%0A%2F%2F%20the%20new%20data%20table%20where%20idn_j%3D%3Didn%20and%20delete%20them%0Aproc%20sql%3B%0A%20create%20table%20allset%20as%0A%20select%20idn_j%2C%20y_j%2C%20x_j%2C%20idn%20as%20idn_i%2C%20surv%20as%20y_i%2C%20combdays%20as%20x_i%0A%20from%20evtset%2C%20obs%0A%20where%20idn_j%26lt%3B%26gt%3Bidn%3B%0Aquit%3B%0A%0A%2F%2F%20This%20step%20just%20creates%20a%20new%20column%20called%20%22concord%22%0A%2F%2F%20SAS%20has%20to%20create%20a%20new%20table%20to%20do%20this%2C%20where%20JMP%20could%0A%2F%2F%20just%20add%20it%20to%20the%20allset%20data%20table%20from%20the%20join%20step%0Adata%20concord%3B%0A%20set%20allset%3B%0A%20if%20(x_i%3CX_J%20and%3D%22%22%20y_i%3D%22%22%3Ey_j)%20or%20(x_i%26gt%3Bx_j%20and%20y_i%3CY_J%3E%3C%2FY_J%3E%3C%2FX_J%3E%3C%2FCODE%3E%3C%2FPRE%3E%3C%2FLINGO-BODY%3E
Choose Language Hide Translation Bar
vince_faller
Super User (Alumni)

Calculating Concordance (C-index) for cox models

I'm trying to calculate concordance index in JMP 10 of a cox model.  I found this paper for SAS:

http://support.sas.com/resources/papers/proceedings09/236-2009.pdf

but am not quite understanding what it is that it's doing.   Any help is appreciated.  

 

proc sql;
 create table allset as
 select idn_j, y_j, x_j, idn as idn_i, surv as y_i, combdays as x_i
 from evtset, obs
 where idn_j<>idn;
quit;
data concord;
 set allset;
 if (x_i<x_j and y_i>y_j) or (x_i>x_j and y_i<y_j) then concord=1;
 else concord=0;
run; 

data _null_;
set concord end=eof;
retain nch ndh;
if _N_=1 then do;
nch=0;
ndh=0;
end;
if concord=1 then nch+1;
if concord=0 then ndh+1;
if eof=1 then do;
 call symput('ch',trim(left(nch)));
 call symput('dh',trim(left(ndh)));
 call symput('uspairs',trim(left(_n_)));
 end; 
run;
data _null_;
set sample end=eof;
if eof=1 then call symput('totobs',trim(left(_n_)));
run;
%put &ch &dh &uspairs &totobs;
data calculat;
ch=input("&ch",12.0);
dh=input("&dh",12.0);
uspairs=input("&uspairs",12.0);
totobs=input("&totobs",10.0);
pc=ch/(totobs*(totobs-1));
pd=dh/(totobs*(totobs-1));
c_hat=pc/(pc+pd);

w=(2*1.96**2)/(totobs*(pc+pd));
low_ci_w=((w+2*c_hat)/(2*(1+w)))-(sqrt((w**2+4*w*c_hat*(1-
c_hat))/(2*(1+w))));
upper_ci_w=((w+2*c_hat)/(2*(1+w)))+(sqrt((w**2+4*w*c_hat*(1-
c_hat))/(2*(1+w))));
run; 
Vince Faller - Predictum
1 ACCEPTED SOLUTION

Accepted Solutions
txnelson
Super User

Re: Calculating Concordance (C-index) for cox models

Here is my review of the SAS code

//This step does a cartesian join of the evtset and obs data tables,
// but eliminates any rows where the column idn_j=idn
// To do this in JMP would be a 2 step process.  Use 
//  Tables==>Join
// and specify to perform a Cartesian Join, then find all rows in 
// the new data table where idn_j==idn and delete them
proc sql;
 create table allset as
 select idn_j, y_j, x_j, idn as idn_i, surv as y_i, combdays as x_i
 from evtset, obs
 where idn_j<>idn;
quit;

// This step just creates a new column called "concord"
// SAS has to create a new table to do this, where JMP could
// just add it to the allset data table from the join step
data concord;
 set allset;
 if (x_i<x_j and y_i>y_j) or (x_i>x_j and y_i<y_j) then concord=1;
 else concord=0;
run; 

// This step simply creates macro variables for the number of rows
// that have been set to a concord value of 1 and 0 and a third 
// variable as to the number of total rows
// JMP would just do this with 3 statements
// ch=N rows(allset<<get rows where(concord==1));
// dh=N Rows(allset)-ch;
// uspairs=N Rows(allset);
data _null_;
 set concord end=eof;
 retain nch ndh;
 if _N_=1 then do;
  nch=0;
  ndh=0;
 end;
 if concord=1 then nch+1;
 if concord=0 then ndh+1;
 if eof=1 then do;
  call symput('ch',trim(left(nch)));
  call symput('dh',trim(left(ndh)));
  call symput('uspairs',trim(left(_n_)));
 end; 
run;

// This step references the original data table "sample" which
// was the input table to the phreg procedure that was run on it.
// This step simply gets the numer of rows from that table
// JMP code would simply be
// totobs=nrows(sample);
data _null_;
 set sample end=eof;
 if eof=1 then call symput('totobs',trim(left(_n_)));
run;

// This simply writes out the calculated macro values
%put &ch &dh &uspairs &totobs;

// This step creates an output data table with one row with the columns
// being calculated starting with the macro variable values
data calculat;
 ch=input("&ch",12.0);
 dh=input("&dh",12.0);
 uspairs=input("&uspairs",12.0);
 totobs=input("&totobs",10.0);
 pc=ch/(totobs*(totobs-1));
 pd=dh/(totobs*(totobs-1));
 c_hat=pc/(pc+pd);

 w=(2*1.96**2)/(totobs*(pc+pd));
 low_ci_w=((w+2*c_hat)/(2*(1+w)))-(sqrt((w**2+4*w*c_hat*(1-c_hat))/(2*(1+w))));
 upper_ci_w=((w+2*c_hat)/(2*(1+w)))+(sqrt((w**2+4*w*c_hat*(1-c_hat))/(2*(1+w))));
run; 
Jim

View solution in original post

1 REPLY 1
txnelson
Super User

Re: Calculating Concordance (C-index) for cox models

Here is my review of the SAS code

//This step does a cartesian join of the evtset and obs data tables,
// but eliminates any rows where the column idn_j=idn
// To do this in JMP would be a 2 step process.  Use 
//  Tables==>Join
// and specify to perform a Cartesian Join, then find all rows in 
// the new data table where idn_j==idn and delete them
proc sql;
 create table allset as
 select idn_j, y_j, x_j, idn as idn_i, surv as y_i, combdays as x_i
 from evtset, obs
 where idn_j<>idn;
quit;

// This step just creates a new column called "concord"
// SAS has to create a new table to do this, where JMP could
// just add it to the allset data table from the join step
data concord;
 set allset;
 if (x_i<x_j and y_i>y_j) or (x_i>x_j and y_i<y_j) then concord=1;
 else concord=0;
run; 

// This step simply creates macro variables for the number of rows
// that have been set to a concord value of 1 and 0 and a third 
// variable as to the number of total rows
// JMP would just do this with 3 statements
// ch=N rows(allset<<get rows where(concord==1));
// dh=N Rows(allset)-ch;
// uspairs=N Rows(allset);
data _null_;
 set concord end=eof;
 retain nch ndh;
 if _N_=1 then do;
  nch=0;
  ndh=0;
 end;
 if concord=1 then nch+1;
 if concord=0 then ndh+1;
 if eof=1 then do;
  call symput('ch',trim(left(nch)));
  call symput('dh',trim(left(ndh)));
  call symput('uspairs',trim(left(_n_)));
 end; 
run;

// This step references the original data table "sample" which
// was the input table to the phreg procedure that was run on it.
// This step simply gets the numer of rows from that table
// JMP code would simply be
// totobs=nrows(sample);
data _null_;
 set sample end=eof;
 if eof=1 then call symput('totobs',trim(left(_n_)));
run;

// This simply writes out the calculated macro values
%put &ch &dh &uspairs &totobs;

// This step creates an output data table with one row with the columns
// being calculated starting with the macro variable values
data calculat;
 ch=input("&ch",12.0);
 dh=input("&dh",12.0);
 uspairs=input("&uspairs",12.0);
 totobs=input("&totobs",10.0);
 pc=ch/(totobs*(totobs-1));
 pd=dh/(totobs*(totobs-1));
 c_hat=pc/(pc+pd);

 w=(2*1.96**2)/(totobs*(pc+pd));
 low_ci_w=((w+2*c_hat)/(2*(1+w)))-(sqrt((w**2+4*w*c_hat*(1-c_hat))/(2*(1+w))));
 upper_ci_w=((w+2*c_hat)/(2*(1+w)))+(sqrt((w**2+4*w*c_hat*(1-c_hat))/(2*(1+w))));
run; 
Jim

Recommended Articles