Skip to content

Instantly share code, notes, and snippets.

@komasaru
Created January 28, 2020 02:49
Show Gist options
  • Save komasaru/51a8341e56a5c9453ce60812a7d089f0 to your computer and use it in GitHub Desktop.
Save komasaru/51a8341e56a5c9453ce60812a7d089f0 to your computer and use it in GitHub Desktop.
Ruby script to calculate a Spearman's Rank Correlation Coefficient.
#! /usr/local/bin/ruby
class Array
def rcc_spearman(y)
# 以下の場合は例外スロー
# - 引数の配列が Array クラスでない
# - 自身配列が空
# - 配列サイズが異なる
# - 数値以外のデータが存在する
raise "Argument is not a Array class!" unless y.class == Array
raise "Self array is nil!" if self.size == 0
raise "Argument array size is invalid!" unless self.size == y.size
(self + y).each do |v|
raise "Items except numerical values exist!" unless v.to_s =~ /[\d\.]+/
end
# ランク付け
rank_x = self.map { |v| self.count { |a| a > v } + 1 }
rank_y = y.map { |v| y.count { |a| a > v } + 1 }
# 同順位を中央(平均)順位(mid-rank)に
rank_x = rank_x.map do |v|
c = rank_x.count(v)
(v...(v + c)).sum / c.to_f
end
rank_y = rank_y.map do |v|
c = rank_y.count(v)
(v...(v + c)).sum / c.to_f
end
# 同順位の数
tai_x = rank_x.group_by { |a| a }.map { |k, v| [k, v.size] }.to_h
tai_y = rank_y.group_by { |a| a }.map { |k, v| [k, v.size] }.to_h
# Tx, Ty の sum 部分
s_x = tai_x.select { |k, v| v > 1 }.map do |a|
a[1] * a[1] * a[1] - a[1]
end.sum
s_y = tai_y.select { |k, v| v > 1 }.map do |a|
a[1] * a[1] * a[1] - a[1]
end.sum
# 相関係数
n = self.size
n3 = n * n * n - n
t_x = (n3 - s_x) / 12.0
t_y = (n3 - s_y) / 12.0
s = rank_x.zip(rank_y).inject(0) { |s, a| s + (a[0] - a[1]) * (a[0] - a[1]) }
return (t_x + t_y - s) / (2 * Math.sqrt(t_x * t_y))
end
end
# タイ(同順位)が存在しない例
#X = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
#Y = [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
# タイ(同順位)が存在する例
X = [1, 2, 3, 4, 5, 5, 7, 8, 9, 10]
Y = [1, 3, 5, 6, 9, 2, 4, 6, 8, 10]
# サイズが異なる例
#X = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
#Y = [1, 3, 5, 7, 9, 2, 4, 6, 8]
# X のサイズがゼロの例
#X = []
#Y = [1, 3, 5, 7, 9, 2, 4, 6, 8, 10]
# 数値以外のものが存在する例
#X = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
#Y = [1, 3, 5, 7, 9, "ABC", 4, 6, 8, 10]
puts " X = #{X}"
puts " Y = #{Y}"
puts " Spearman's RCC = #{X.rcc_spearman(Y)}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment