s_utl_rank Subroutine

public pure subroutine s_utl_rank(x, ranks)

Ranks all samples such that the smallest value obtains rank 1 and the largest rank n. Handles tied ranks and assigns average rank to tied elements within one group of tied elements.

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in) :: x(:)

x array

real(kind=wp), intent(out), allocatable :: ranks(:)

ranks of x


Called by

proc~~s_utl_rank~~CalledByGraph proc~s_utl_rank s_utl_rank interface~fsml_rank fsml_rank interface~fsml_rank->proc~s_utl_rank proc~s_tst_kruskalwallis_core s_tst_kruskalwallis_core proc~s_tst_kruskalwallis_core->proc~s_utl_rank proc~s_tst_ranksum_core s_tst_ranksum_core proc~s_tst_ranksum_core->proc~s_utl_rank proc~s_tst_signedrank_1s_core s_tst_signedrank_1s_core proc~s_tst_signedrank_1s_core->proc~s_utl_rank proc~s_tst_kruskalwallis s_tst_kruskalwallis proc~s_tst_kruskalwallis->proc~s_tst_kruskalwallis_core proc~s_tst_ranksum s_tst_ranksum proc~s_tst_ranksum->proc~s_tst_ranksum_core proc~s_tst_signedrank_1s s_tst_signedrank_1s proc~s_tst_signedrank_1s->proc~s_tst_signedrank_1s_core proc~s_tst_signedrank_2s_core s_tst_signedrank_2s_core proc~s_tst_signedrank_2s_core->proc~s_tst_signedrank_1s_core interface~fsml_kruskalwallis fsml_kruskalwallis interface~fsml_kruskalwallis->proc~s_tst_kruskalwallis interface~fsml_ranksum fsml_ranksum interface~fsml_ranksum->proc~s_tst_ranksum interface~fsml_signedrank_1sample fsml_signedrank_1sample interface~fsml_signedrank_1sample->proc~s_tst_signedrank_1s proc~s_tst_signedrank_2s s_tst_signedrank_2s proc~s_tst_signedrank_2s->proc~s_tst_signedrank_2s_core interface~fsml_signedrank_paired fsml_signedrank_paired interface~fsml_signedrank_paired->proc~s_tst_signedrank_2s

Source Code

pure subroutine s_utl_rank(x, ranks)

! ==== Description
!! Ranks all samples such that the smallest value obtains rank 1
!! and the largest rank n. Handles tied ranks and assigns average
!! rank to tied elements within one group of tied elements.

! ==== Declarations
  real(wp)                , intent(in)  :: x(:)     !! x array
  real(wp)   , allocatable, intent(out) :: ranks(:) !! ranks of x
  integer(i4), allocatable              :: idx(:)   !! index vector to sort x
  real(wp)                              :: rank_sum !! sum of tied ranks
  integer(i4)                           :: cnt      !! counter
  integer(i4)                           :: n        !! size of x
  integer(i4)                           :: i, j, k  !! loop control & flexible

! ==== Instructions

  ! allocate
  n = size(x)
  allocate(idx(n))
  allocate(ranks(n))

! ---- create index vector

  ! create index vector
  do i = 1, n
     idx(i) = i
  enddo

  ! sort index based on x
  do i = 2, n
     do j = i, 2, -1
        if (x(idx(j)) .lt. x(idx(j-1))) then
           k = idx(j)
           idx(j) = idx(j-1)
           idx(j-1) = k
        else
           exit
        endif
     enddo
  enddo

! ---- get rank sums

  ! assign ranks (with tie averaging)
  i = 1
  do while (i .le. n)

     ! initialise rank sum and reset counter for tie group
     rank_sum = real(i, kind=wp)
     cnt = 1

     ! check for ties
     do j = i + 1, n
        if (x(idx(j)) .eq. x(idx(i))) then
           rank_sum = rank_sum + real(j, kind=wp)
           cnt = cnt + 1
        else
           exit
        endif
     enddo

     ! average rank for tie group
     rank_sum = rank_sum / real(cnt, kind=wp)

     ! assign average rank to all tied elements
     do k = i, i + cnt - 1
        ranks(idx(k)) = rank_sum
     enddo

     ! advance to next group
     i = i + cnt
  enddo

  ! deallocate
  deallocate(idx)

end subroutine s_utl_rank