cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
  • Register to attend Discovery Summit 2025 Online: Early Users Edition, Sept. 24-25.
  • New JMP features coming to desktops everywhere this September. Sign up to learn more at jmp.com/launch.
Choose Language Hide Translation Bar
aquastralis
Level I

Mann Kendall

Hi all. I'm trying to run a Mann-Kendall to test if a temporal trend is significant. Can't find it in the JMP manual or anything online. Anyone have any ideas?

Thanks!

1 ACCEPTED SOLUTION

Accepted Solutions
ms
Super User (Alumni) ms
Super User (Alumni)

Mann Kendall

Even if the definitions Mann-Kendall test statistic and the Kendall Tau b often is described in different terms (from time series and correlation perspectives, respectively), they are essentially the same as far as I can tell.

Below is a script I wrote quite long ago. It calculates and shows the Theil's slope and performs the Mann-Kendall test. A parametric linear regression line is shown in the plot just for comparision. I planned to generalize the script by include a "By" function as well as the posibilty to account for seasonal patterns. But I have not had the time to realize those plans yet. I hope this will give you some ideas.

dt = Current Data Table();

dlg = Column Dialog(

  "Estimate Theil slope and Kendall Tau from Data Table " ||

          Char( dt << get name ),

          Ys = ColList( "Select Y",

                    maxcol( 1 ),

                    mincol( 1 ),

                    Datatype( numeric )

          ),

          Xs = ColList( "Select X",

                    maxcol( 1 ),

                    mincol( 1 ),

                    Datatype( numeric )

          ),

          Group = ColList( "By (not working)", maxcol( 1 ) )

);

colY = Column( dt, dlg["Ys"] );

colX = Column( dt, dlg["Xs"] );

colGroup = Column( dt, dlg["Group"] );

//Calculation of Theil slope

n = N Rows( dt );

slopes = J( n, n, . );

For( i = 1, i < n, i++,

          For( j = i + 1, j <= n, j++,

                    slopes[i, j] = (colY[j] - colY[i]) / (colX[j] - colX[i])

          )

);

theil = Quantile( 0.5, slopes );

//Kendall's Tau b to test if slope differs from zero

mv = Multivariate(

          Y( colY, colX ),

          Scatterplot Matrix(0),

          Correlations multivariate(0),

          Kendall's Tau( 1 )

);

//Plot data and add linear regression and Theil's slope

biv = Bivariate(

          Y( colY ),

          X( colX ),

          Fit Line( {Line Color( "Red" )} ),

          Fit Special( Slope( theil ), {Line Color( "Green" )} ),

          invisible

);

rbiv = biv << report;

rbiv["Linear Fit"] << close all like this;

rbiv[Outline Box( 7 )] << set title( "Theil's Slope" );

db = Report( mv )["Multivariate"] << parent;

db << prepend( rbiv );

db[Text Box( 4 )] << set text( "Theil's Slope" );

rbiv << close window;

View solution in original post

4 REPLIES 4
David_Burnham
Super User (Alumni)

Re: Mann Kendall

I'm not sure to what degree (if at all) the Mann-Kendall test is related to the Kendall Tau statistic for non-parametric correlation.  The later can be accessed under the multivariate platform: Analyze>Multivariate Methods then from the multivariate report select Nonparametric Correlations from the hotspot.

If the tests are completely different I'd be interested in any references that you have for this method.  I'm considering building an add-in that implements a number of methods (e.g. Hurst Index) that have been developed for the field of hydrology

Regards


Dave

-Dave
ms
Super User (Alumni) ms
Super User (Alumni)

Mann Kendall

Even if the definitions Mann-Kendall test statistic and the Kendall Tau b often is described in different terms (from time series and correlation perspectives, respectively), they are essentially the same as far as I can tell.

Below is a script I wrote quite long ago. It calculates and shows the Theil's slope and performs the Mann-Kendall test. A parametric linear regression line is shown in the plot just for comparision. I planned to generalize the script by include a "By" function as well as the posibilty to account for seasonal patterns. But I have not had the time to realize those plans yet. I hope this will give you some ideas.

dt = Current Data Table();

dlg = Column Dialog(

  "Estimate Theil slope and Kendall Tau from Data Table " ||

          Char( dt << get name ),

          Ys = ColList( "Select Y",

                    maxcol( 1 ),

                    mincol( 1 ),

                    Datatype( numeric )

          ),

          Xs = ColList( "Select X",

                    maxcol( 1 ),

                    mincol( 1 ),

                    Datatype( numeric )

          ),

          Group = ColList( "By (not working)", maxcol( 1 ) )

);

colY = Column( dt, dlg["Ys"] );

colX = Column( dt, dlg["Xs"] );

colGroup = Column( dt, dlg["Group"] );

//Calculation of Theil slope

n = N Rows( dt );

slopes = J( n, n, . );

For( i = 1, i < n, i++,

          For( j = i + 1, j <= n, j++,

                    slopes[i, j] = (colY[j] - colY[i]) / (colX[j] - colX[i])

          )

);

theil = Quantile( 0.5, slopes );

//Kendall's Tau b to test if slope differs from zero

mv = Multivariate(

          Y( colY, colX ),

          Scatterplot Matrix(0),

          Correlations multivariate(0),

          Kendall's Tau( 1 )

);

//Plot data and add linear regression and Theil's slope

biv = Bivariate(

          Y( colY ),

          X( colX ),

          Fit Line( {Line Color( "Red" )} ),

          Fit Special( Slope( theil ), {Line Color( "Green" )} ),

          invisible

);

rbiv = biv << report;

rbiv["Linear Fit"] << close all like this;

rbiv[Outline Box( 7 )] << set title( "Theil's Slope" );

db = Report( mv )["Multivariate"] << parent;

db << prepend( rbiv );

db[Text Box( 4 )] << set text( "Theil's Slope" );

rbiv << close window;

aquastralis
Level I

Mann Kendall

thanks MS and Dave! I was not sure if Kendall's Tau and the Mann-Kendall test were the same (and/or related) either. Thanks for the info on the multivariate test and then for the script as well!

Re: Mann Kendall

Hi, Here's an update to this script which covers the situation where a column in the By Role (with 2 levels) is specified, using the Big Class example. 

dt = Open( "$SAMPLE_DATA/Big Class.jmp" );

dlg = Column Dialog(

	"Estimate Theil slope and Kendall Tau from Data Table " || 
	Char( dt << get name ), 
	Ys = ColList( "Select Y", 
		maxcol( 1 ), 
		mincol( 1 ), 
		Datatype( numeric )
	), 

	Xs = ColList( "Select X", 
		maxcol( 1 ), 
		mincol( 1 ), 
		Datatype( numeric )
	), 
	Group = ColList( "By", maxcol( 1 ) )
);

colY = Column( dt, dlg["Ys"] );
colX = Column( dt, dlg["Xs"] );
colGroup = Column( dt, dlg["Group"] ); 

//create subset data tables when By Role is used
subdt = dt << Subset(
	By( :sex ),
	All rows,
	Selected columns only( 0 ),
);

//hide subset data tables, for 2 levels of the Group column in the By Role
subdt[1] << Show Window(0);
subdt[2] << Show Window(0);

//Calculation of Theil-Sen slope: A robust non-parametric estimate of trend magnitude.

theil = {}; //create empty list call 'theil'to store Theil-Sen slopes

for (k = 1, k <= Nitems(subdt), k++,
	curY = Column( subdt[k], dlg["Ys"] );
	curX = Column( subdt[k], dlg["Xs"] );
	

	n = N Rows( subdt[k] );
	slopes = J( n, n, . ); //this is initialized not as an empty matrix but it's full of missing values
	
For( i = 1, i < n, i++, 
	For( j = i+1, j <= n, j++, 
		slopes[i, j] = (curY[j] - curY[i]) / (curX[j] - curX[i])
	)
);

insert into(theil, Quantile( 0.5, slopes )); //calculate the median of all the slopes
);

new window("windowname",

/*Kendall's Tau b to test if slope differs from zero. Analogous to the Mann-Kendall significance test, which Outputs the S statistic and p-value.*/

mv = dt << Multivariate(
	Y( colY, colX ), 
	Scatterplot Matrix( 0 ), 
	Correlations multivariate( 0 ), 
	Kendall's Tau( 1 ), /*see above*/
	By(colGroup)
);

//Plot data and add linear regression and Theil's slope

biv = dt << Bivariate(
	Y( colY ), 
	X( colX ), 
	By(colGroup),
	Fit Line( {Line Color( "Red" )} ), 
	//invisible
);
);

//Plot Theil's Slopes using Fit special in Bivariate report
biv[1] << Fit Special( Slope( theil[1] ), {Line Color( "Green" )});
biv[2] << Fit Special( Slope( theil[2] ), {Line Color( "Green" )});

rbiv = biv << Report;

rbiv[1]["Linear Fit"] << close all like this;


//all of the second linear fit outline boxes under an outline box that contains the word "sex" in the title is what I want

tsb = rbiv << Xpath("(//OutlineBox[text()='Linear Fit'])[2]");  //this returns the list of display boxes titled "Linear Fit" that I want to change to "Thiel's slope" and then I am capturing this reference with the variable name tsb


tsb << set title( "Theil's Slope" );

Recommended Articles