1

我有一个如下所示的 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)。

例如:列“Name1”
第一个元素 = 1:分数 = 1(起始位置)
第二个元素 = -1:分数 = 0(从前一个分数 (1) 中删除 1 个单位,因为 1 != -1)
第三个元素 = 1 :score = 1(你正在将score初始化为1。每次初始化时,score都是+1)。
第四个元素 = 1:分数 = 2(之前的分数 1 加上 1 个单位,因为第三个和第四个元素相等)
第五个元素 = -1:分数 = 1(之前的分数 2 - 1 个单位,因为第四个元素!= 第五个元素)。

列“Name2”
第一个元素 = 1:分数 = 1(起始位置)
第二个元素 = -1:分数 = 0(从前一个分数 (1) 中删除 1 个单位,因为 1 != -1)
第三个元素 = -1: score = 1(您正在重新初始化分数)
第四元素 = -1:分数 = 2(第三元素等于第四元素,因此前一个分数将增加 1 个单位)
第五元素 = -1:分数 = 3(第四元素等于第五个所以之前的分数,所以 2,将增加 1 个单位)

因此,如果排名中的元素与前一个元素相同或不同,计数器将增加或减少一个数字的分数 == 1,并且每次它变为 0 时都会初始化为 1。

最终目标是相对于随机元素,对等级中的相等和连续元素给予更高的分数。

任何人都可以帮助我吗?

4

5 回答 5

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
于 2013-06-11T19:47:10.310 回答
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 
于 2013-06-11T20:02:30.033 回答
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取值。

于 2013-06-11T20:18:56.983 回答
0

将 1 添加到相等测试以构造 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 
于 2013-06-11T19:49:10.633 回答
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 
于 2013-06-11T19:30:06.007 回答