根据之前的评分创建顺序排名
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")
我在按顺序更新排名时遇到问题,无论我如何尝试寻找解决方案 - 或者自己想出一个 - 我都失败了。
我正在尝试分析顺序选择实验的结果,在该实验中,参与者必须找到可能的最佳选项(评分最高的选项)。他们在每次试验中都会获得评分。
对于每个选择,我都有一个 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")