我有一个看起来像这样的data.frame:
Name1 Name2 Name3 1 1 1 -1 -1 1 1 -1 1 1 -1 1 -1 -1 1
我想对每一列执行一种秩和检验,以便:
从每列的第一个元素开始(因此对于我的data.frame的每个列表) 如果第二个元素等于第一个元素(例如:1和1),则分数将增加一个单位,因为它们是等于的,否则分数将减少一个整数(因为它们是不等的,例如:1和-1)。
例如:列"名称1"
第一个元素= 1:得分= 1(起始位置)
第二个元素= -1:得分= 0(从前一个得分(1)中删除1个单位,因为1!= -1)
第三个元素= 1:得分= 1(您将分数初始化为1.每次初始化时,分数为+1)。
第四个元素= 1:得分= 2(前一个得分1加1个单位,因为第三个和第四个要素相等)
第五个元素= -1:得分= 1(前一个得分为2 - 1单位,因为第四个元素!=第五个元素)。
栏"名称2"
第一个元素= 1:得分= 1(起始位置)
第二个元素= -1:得分= 0(从前一个得分(1)中删除1个单位,因为1!= -1)
第三个元素= -1:得分= 1(你正在重新初始化得分)
第四个元素= -1:得分= 2(第三个元素等于第四个元素,因此先前的分数将增加1个单位)
第五个元素= -1:得分= 3(第四个元素等于第五个元素,所以前一个得分,所以2,将增加1个单位)
因此,如果排名中的元素与前一个元素相同或不同,则计数器将增加或减少数字== 1的分数,并且每次进入0时它将被初始化为1。
最终目标是给予等级中的等于和连续元素的更高分数。
有人能帮帮我吗?
答案 0 :(得分:2)
如果我理解正确的话......
d <- read.table(text="Name1 Name2 Name3
1 1 1
-1 -1 1
1 -1 1
1 -1 1
-1 -1 1", header=TRUE)
f1 <- function(score, pair) {
if (score == 0) pair[1]
else if (as.logical(diff(pair))) score - 1
else score + 1
}
f2 <- function(col) {
lagged <- embed(col, 2)
Reduce(f1, split(lagged, seq(nrow(lagged))), init=1)
}
lapply(d, f2)
# $Name1
# [1] 1
#
# $Name2
# [1] -1
#
# $Name3
# [1] 5
答案 1 :(得分:1)
这是对你后续问题的回答,而不是第一个问题,我相信Matthew Plourde已回答过。
要获得所需等级的度量,您可以计算连续多次具有相同数字的列的长度总和。例如,在下面的示例中,您可以添加3和2并获得5的等级。
x = c(1,-1,1,1,1,-1,-1)
rle(x)
#Run Length Encoding
# lengths: int [1:4] 1 1 3 2
# values : num [1:4] 1 -1 1 -1
把它放在一个函数中:
rank = function(x) {
x.rle = rle(x)
sum(x.rle$lengths[x.rle$lengths > 1])
}
sapply(OP_dat, rank)
#Name1 Name2 Name3
# 2 4 5
答案 2 :(得分:0)
考虑这个功能:
f <- function(x)
{
2 * sum(tail(x, -1)==head(x, -1)) - length(x) + 1
}
它计算您建议的分数,即等于前一个元素的数量减去不同元素的数量。由于最后一个数字与第一个数字互补,因此可以用上面的简化形式编写函数。
现在,如果您想将其应用于数据框的所有列,只需使用sapply
:
dat <- read.table(header=TRUE, text="
Name1 Name2 Name3
1 1 1
-1 -1 1
1 -1 1
1 -1 1
-1 -1 1
")
sapply(dat, f)
# Name1 Name2 Name3
# -2 2 4
答案 3 :(得分:0)
在等式测试中添加一个以构造1和2的索引以从c(-1,1)中选择
func <- function(x) 1+ # your "starting position"
sum( c(-1, 1)[1+ # convert from 0/1 to 1/2
(x[-1] == x[-length(x)]) ])
> sapply(dat, func)
Name1 Name2 Name3
-2 2 4
答案 4 :(得分:0)
这可能会有所帮助。
dat <- read.table(header=TRUE, text="
Name1 Name2 Name3
1 1 1
-1 -1 1
1 -1 1
1 -1 1
-1 -1 1
")
f <- function(x) {
tail(cumsum(x), 1)
}
sapply(dat, f)
#Name1 Name2 Name3
# 1 -3 5
如果您想比较这些结果,您可能需要abs
个值。