#==========
Julia の修行をするときに,いろいろなプログラムを書き換えるのは有効な方法だ。
以下のプログラムを Julia に翻訳してみる。
フリードマン検定(plus 多重比較)
http://aoki2.si.gunma-u.ac.jp/R/friedman.html
ファイル名: friedman.jl 関数名: friedman
翻訳するときに書いたメモ
内包表記より,for ループの方がわかりやすいかな。
==========#
using StatsBase, Rmath, Combinatorics, Printf
function friedman(dat)
row, col = size(dat)
df = col - 1
o = similar(dat, Float64)
ties = 0
for i = 1:row
rank = tiedrank(dat[i, :])
tie = [count(isequal(s), rank) for s in Set(rank)]
ties += sum(tie .^ 3 .- tie)
o[i, :] = rank
end
R = sum(o, dims=1)
chi = 12 * sum((R .- row * (col + 1) / 2) .^ 2) / (row * col * (col + 1) - ties / (col - 1))
pvalue = pchisq(chi, df, false)
println("chisq. = $chi, df = $df, p value = $pvalue")
Rm = R / row
V = sum((o .- (col + 1) / 2) .^ 2)
S = []
P = []
@printf("%2s: %2s %7s %9s\n", "i", "j", "Chi sq.", "p value")
for (i, j) in combinations(1:col, 2)
s = row^2*df*(Rm[i] - Rm[j])^2/(2*V)
append!(S, s)
p = pchisq(s, df, false)
append!(P, p)
@printf("%2d: %2d %7.3f %9.7f\n", i, j, s, p)
end
Dict(:chisq => chi, :df => df, :pvalue => pvalue, :S => S, :P => P)
end
dat = [ 5 60 35 62 76
24 44 74 63 76
56 57 70 74 79
44 51 55 23 84
8 68 50 24 64
32 66 45 63 46
25 38 70 58 77
48 24 40 80 72];
friedman(dat)
# chisq. = 15.9, df = 4, p value = 0.0031563263734228895
# i: j Chi sq. p value
# 1: 2 3.600 0.4628369
# 1: 3 4.225 0.3764110
# 1: 4 5.625 0.2289584
# 1: 5 15.625 0.0035659
# 2: 3 0.025 0.9999225
# 2: 4 0.225 0.9941270
# 2: 5 4.225 0.3764110
# 3: 4 0.100 0.9987909
# 3: 5 3.600 0.4628369
# 4: 5 2.500 0.6446358
x = [9 17 12 16; 5 21 16 11; 7 19 6 9; 8 11 11 8; 9 8 9 9; 2 4 5 8; 3 8 10 9];
friedman(x)
# chisq. = 6.1875, df = 3, p value = 0.10283586999577443
# i: j Chi sq. p value
# 1: 2 4.687 0.1961632
# 1: 3 3.797 0.2842498
# 1: 4 3.797 0.2842498
# 2: 3 0.047 0.9973385
# 2: 4 0.047 0.9973385
# 3: 4 0.000 1.0000000
x = [9 17 12 16; 1 21 16 11; 7 19 6 9];
friedman(x)
# chisq. = 7.0, df = 3, p value = 0.07189777249646513
# i: j Chi sq. p value
# 1: 2 6.400 0.0936908
# 1: 3 0.400 0.9402425
# 1: 4 1.600 0.6593898
# 2: 3 3.600 0.3080222
# 2: 4 1.600 0.6593898
# 3: 4 0.400 0.9402425