根据之前的评分创建顺序排名

Creating a sequential ranking based on previous ratings

我在按顺序更新排名时遇到问题,无论我如何尝试寻找解决方案 - 或者自己想出一个 - 我都失败了。

我正在尝试分析顺序选择实验的结果,在该实验中,参与者必须找到可能的最佳选项(评分最高的选项)。他们在每次试验中都会获得评分。

对于每个选择,我都有一个 ID、一个 order 和一个 rating 变量。 ID为参与者,rating代表选项好坏(评分越高越好),order 是试验次数(本例中有 4 次试验)

ID       rating        order
1        4             1
1        3             2
1        5             3
1        2             4
2        3             1
2        5             2
2        2             3
2        1             4

我想创建一个名为 "current_rank" 的新变量,它基本上是当前选择的评级排名。这个变量总是需要考虑所有以前的试验和评级,例如对于 ID“1”的参与者,这将是:

试用 1:评分 = 4,这意味着这是迄今为止最好的评分,current_rank = 1

试验 2:评分 = 3,这意味着这是迄今为止第二好的评分,current_rank = 2

试验 3:评级 = 5,这意味着这是迄今为止最好的评级,使其成为新的数字 1 所以,current_rank = 1

试用 4:评级 = 2,这意味着这远非最佳,current_rank = 4

如果我可以对所有参与者和所有选项执行此操作,我的数据库应该如下所示:

ID       rating        order        current_rank
1        4             1            1
1        3             2            2
1        5             3            1
1        2             4            4
2        3             1            1
2        5             2            1
2        2             3            3
2        1             4            4

我可以像这样成功创建一个整体排名变量:

db %>%
  arrange(ID, order) %>%
  group_by(ID) %>%
  mutate(ovr_rank = min_rank(desc(rating)))

但我的目标是创建一个变量,它是一种顺序排名。这样就可以在不知道未来评级可能是什么的情况下,根据之前的评级了解参与者可能对当前评级形成什么样的意见。我尝试创建循环或使用应用函数,但还没有想出解决方案。

非常感谢任何和所有想法!

这段代码可以工作:

df <- tibble(
  ID = c(1,1,1,1,2,2,2,2),
  rating = c(4,3,5,2,3,5,2,1),
  rank = c(1,0,0,0,0,0,0,0)
)

for(i in 2:nrow(df)){
  if(df$ID[i] != df$ID[i-1]){
    df$rank[i] <- 1
  } else {
    df$rank[i] <- which(sort(df[1:i,]$rating[which(df$ID == df$ID[i])], decreasing = TRUE) == df$rating[i])
  }
}

解释:

请注意,我假设您的数据框已经根据 ID 和顺序进行了排序。在我的 df 中没有 order 列,但这主要是为了简单起见(我的解决方案中不一定需要它,再次假设行已经按 ID 和顺序排序)。

for 循环只是简单地查看该行的 ID 是否与上面的行不同,它会自动获得等级 1。否则,它会查看 df 从第 1 行到第 1 行的子集row i, subsets again by similar ID, sort the ratings in that subset (including our current ratings in question) 按降序排序,并将我们当前要求的评级的位置作为其排名值。

我希望这能回答您的问题并让您有所了解。

使用 runner 以累积 window(或滚动 window)应用任何 R 函数。下面我使用了 runner,它滚动评分并在 "available" 数据上应用排名函数(累积排名)。取消注释 print 以展示进入 function(x) 的内容。

library(dplyr)
library(runner)

data %>%
  arrange(ID, order) %>%
  group_by(ID) %>%
  mutate(
    current_rank = runner(
      x = rating,
      f = function(x) {
        # print(x)
        rank_available_at_the_moment <- rank(-x, ties.method = "last")
        tail(rank_available_at_the_moment, 1)
      }
    )
  )


# # A tibble: 8 x 4
# # Groups:   ID [2]
#       ID rating order current_rank
#     <int>  <int> <int>        <int>
# 1     1      4     1            1
# 2     1      3     2            2
# 3     1      5     3            1
# 4     1      2     4            4
# 5     2      3     1            1
# 6     2      5     2            1
# 7     2      2     3            3
# 8     2      1     4            4

数据

data <- read.table(text = "ID       rating        order
1        4             1
1        3             2
1        5             3
1        2             4
2        3             1
2        5             2
2        2             3
2        1             4", header = TRUE)

这里有 2 个选项使用 data.table:

1) non-equi join 查找之前的所有试验,包括当前试验,对评级进行排名并提取当前排名:

DT[, cr := .SD[.SD, on=.(ID, trial<=trial), by=.EACHI, order(order(-rating))[.N]]$V1]

2) non-equi join 查找在当前试验之前的试验中高于当前等级的等级数:

DT[, cr2 := DT[DT, on=.(ID, trial<=trial, rating>rating), by=.EACHI, .N + 1L]$V1]

请注意,收视率可能存在联系,最好指定应如何处理收视率联系。

输出:

   ID rating trial cr cr2
1:  1      4     1  1   1
2:  1      3     2  2   2
3:  1      5     3  1   1
4:  1      2     4  4   4
5:  2      3     1  1   1
6:  2      5     2  1   1
7:  2      2     3  3   3
8:  2      1     4  4   4

数据:

library(data.table)
DT <- fread("ID       rating        trial
1        4             1
1        3             2
1        5             3
1        2             4
2        3             1
2        5             2
2        2             3
2        1             4")