我正在尝试重复"手动" this Wikipedia post中使用R。
的示例以下是数据:
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签名测试中忽略了零。
如何让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
答案 0 :(得分:3)
您可以创建新列,然后只更新abs值不为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 :(得分:3)
来自维基百科的文章:
- 排除 | x 2, i - x 1,< EM> I 的子> | = 0 。让 N r 减少样本量。
醇>
我们需要排除零。根据我的想法,你应该用NA替换零,然后指定你要排除考虑排名的N rank()
。由于您需要返回与输入长度相同的向量,因此可以指定'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
如果输入向量包含零个零或多个零,则基于减法的解决方案将不起作用。
答案 2 :(得分:1)
一种快速的方法是按正常排名,然后执行:
d$rank <- ifelse(d$rank == 1, 0, d$rank - 1)
这会将1
的所有等级切换为0
,并将所有其他等级减少1
。