2016-08-11 64 views
1

我試圖複製「手動」使用R.排名()中的R不包括零

在這裏,在this Wikipedia post的例子是數據:

after = c(125, 115, 130, 140, 140, 115, 140, 125, 140, 135) 
before = c(110, 122, 125, 120, 140, 124, 123, 137, 135, 145) 
sgn = sign(after-before) 
abs = abs(after - before) 
d = data.frame(after,before,sgn,abs) 

    after before sgn abs 
1 125 110 1 15 
2 115 122 -1 7 
3 130 125 1 5 
4 140 120 1 20 
5 140 140 0 0 
6 115 124 -1 9 
7 140 123 1 17 
8 125 137 -1 12 
9 140 135 1 5 
10 135 145 -1 10 

如果我試圖排名基於行在abs列中,0項自然排名爲1

rank = rank(abs) 
(d = data.frame(after,before,sgn,abs,rank)) 

    after before sgn abs rank 
1 125 110 1 15 8.0 
2 115 122 -1 7 4.0 
3 130 125 1 5 2.5 
4 140 120 1 20 10.0 
5 140 140 0 0 1.0 
6 115 124 -1 9 5.0 
7 140 123 1 17 9.0 
8 125 137 -1 12 7.0 
9 140 135 1 5 2.5 
10 135 145 -1 10 6.0 

然而,零忽略了Wilcoxon符號-T美東時間。

我怎樣才能得到R鍵忽略該行,以便與結束:

after before sgn abs rank 
1 125 110 1 15 7.0 
2 115 122 -1 7 3.0 
3 130 125 1 5 1.5 
4 140 120 1 20 9.0 
5 140 140 0 0 0 
6 115 124 -1 9 4.0 
7 140 123 1 17 8.0 
8 125 137 -1 12 6.0 
9 140 135 1 5 1.5 
10 135 145 -1 10 5.0 

的溶液(低於接受的答案):

after = c(125, 115, 130, 140, 140, 115, 140, 125, 140, 135) 
before = c(110, 122, 125, 120, 140, 124, 123, 137, 135, 145) 
sgn = sign(after-before) 
abs = abs(after - before) 
d = data.frame(after,before,sgn,abs) 
d$rank = rank(replace(abs,abs==0,NA), na='keep') 
d$multi = d$sgn * d$rank 

(W=abs(sum(d$multi, na.rm = T))) 
9 
+3

'rank(abs) - 1'? –

回答

3

從維基百科文章:

  • 排除與對| X 2, - X 1, | = 0。令Nr是縮小的樣本量。
  • 我們需要排除零。按照我的想法,你應該用NA代替零,然後指定rank()你想排除NAs排名的考慮因素。既然你需要返回相同長度的輸入向量,你可以指定'keep'作爲參數:如果輸入向量包含零零或多個零

    d$rank <- rank(replace(abs,abs==0,NA),na='keep'); 
    d; 
    ## after before sgn abs rank 
    ## 1 125 110 1 15 7.0 
    ## 2 115 122 -1 7 3.0 
    ## 3 130 125 1 5 1.5 
    ## 4 140 120 1 20 9.0 
    ## 5 140 140 0 0 NA 
    ## 6 115 124 -1 9 4.0 
    ## 7 140 123 1 17 8.0 
    ## 8 125 137 -1 12 6.0 
    ## 9 140 135 1 5 1.5 
    ## 10 135 145 -1 10 5.0 
    

    基於減法的解決方案將無法正常工作。

    +0

    我不知道我是否可以打擾你的後續問題......當我在R中運行測試爲'wilcox.test(d $ after,d $ before,paired = T)'時,我得到一個'V = 27 ',或'V = 18',而不是維基百科條目中計算出的'9'。你知道我錯過了什麼嗎? – Toni

    +0

    @Toni我剛剛查看了'wilcox.test()'的源代碼,它通過S3 dispatch調用'stats ::: wilcox.test.default()'。罪魁禍首是他們實際計算測試統計值的語句:'STATISTIC < - setNames(sum(r [x> 0]),「V」)',其中'r'是正確的等級向量,'x '是兩個樣本向量(「之後」和「之前」)之間的(非絕對)差異。根據維基百科的文章,這個總和表達式應該是'sum(r * sign(x))',它給出9.他們的表達式'sum(r [x> 0])'給出27. – bgoldst

    +0

    看起來好像有些不一致在統計學世界中,究竟應該如何完成這個測試;例如,請參閱http://stats.stackexchange.com/questions/65844/wilcoxon-rank-sum-test-in-r。 – bgoldst

    3

    您可以創建新的然後只更新絕對值不爲0的等級0

    d$rank <- 0 # default value for rows with abs=0 
    d$rank[d$abs!=0] <- rank(d$abs[d$abs!=0]) 
    

    如果你想完全刪除該行,你可以只是做

    transform(subset(d, abs!=0), rank=rank(abs)) 
    
    1

    一個快速的方法來做到這將是列爲正常的,然後做:

    d$rank <- ifelse(d$rank == 1, 0, d$rank - 1) 
    

    這種切換的所有行列10,並減少1的任何其他等級。

    +2

    這與「d $ rank = d $ rank - 1」有什麼不同? – Gregor

    +0

    我想不是,但是ifelse至少可以讓你在腳本改變時選擇其他值。例如,如果您想要插入「NA」值。 – jdobres

    +1

    @Gregor在'abs'中沒有零時是不正確的我想 –