我想对每个小时ID中的每个小时值进行排名。彼此相等的小时值将是相同的等级。我试图用data.table中的行计数函数(.N)来做到这一点。我希望这能奏效,但我无法弄清楚。
这是一个可复制的示例,如果您对我的问题有任何疑问,请让我知道。
library(data.table)
dt <- data.table(hours=c(100, 72, 48, 98, 87, 75, 98, 75, 52, 48, 100, 98, 87, 35, 48, 75, 92, 100, 75, 48),
id=rep(1:4, each=5, 1))
dt <- dt[, list(.(hours <= hours), .N), list(hours, id)]
任何帮助将不胜感激。
[更新]:
这个问题的附带目标是获得不同“ id”组随时间的死亡率。这是通过以下代码完成的,我还提供了一个很酷的图形来显示一段时间内的这种关系。该代码改编自akrun使用data.table软件包中的frankv()函数提供的答案。
library(ggplot2)
dt <- dt[,list(tot=.N, hours=hours), list(id)]
dt[, rank.total := frankv(hours, ties.method = 'max'), id]
dt[, death:= rank.total/tot, id]
dt[, alive:= 1-death, id]
ggplot(dt, aes(x=hours, y=alive, color=as.factor(id))) +
geom_line() +
geom_point() +
theme_minimal() +
labs(x="Hours", y="% Alive", title= "Death rate over time", color="Group")
我们可以使用match
library(data.table)
dt[, rank.total := match(hours, unique(hours)), id]
如果需要反转排名,请使用frank
dt[, rank.total := frank(-hours, ties.method = 'dense'), id]
dt
# hours id rank.total
# 1: 100 1 1
# 2: 72 1 4
# 3: 48 1 5
# 4: 98 1 2
# 5: 87 1 3
# 6: 75 2 2
# 7: 98 2 1
# 8: 75 2 2
# 9: 52 2 3
#10: 48 2 4
#11: 100 3 1
#12: 98 3 2
#13: 87 3 3
#14: 35 3 5
#15: 48 3 4
#16: 75 4 3
#17: 92 4 2
#18: 100 4 1
#19: 75 4 3
#20: 48 4 4
要更改其通常的顺序
dt[, rank.total := frank(hours, ties.method = 'dense'), id]
dt
# hours id rank.total
# 1: 100 1 5
# 2: 72 1 2
# 3: 48 1 1
# 4: 98 1 4
# 5: 87 1 3
# 6: 75 2 3
# 7: 98 2 4
# 8: 75 2 3
# 9: 52 2 2
#10: 48 2 1
#11: 100 3 5
#12: 98 3 4
#13: 87 3 3
#14: 35 3 1
#15: 48 3 2
#16: 75 4 2
#17: 92 4 3
#18: 100 4 4
#19: 75 4 2
#20: 48 4 1
或带有match
dt[, rank.total := match(hours, rev(sort(unique(hours)))), id]
您可以将hours
转换为factor
,然后转换为integer
,这将根据所需的输出自动正确处理领带。
library(data.table)
dt[, rank.total := as.integer(factor(hours)), id]
dt
# hours id rank.total
# 1: 100 1 5
# 2: 72 1 2
# 3: 48 1 1
# 4: 98 1 4
# 5: 87 1 3
# 6: 75 2 3
# 7: 98 2 4
# 8: 75 2 3
# 9: 52 2 2
#10: 48 2 1
#11: 100 3 5
#12: 98 3 4
#13: 87 3 3
#14: 35 3 1
#15: 48 3 2
#16: 75 4 2
#17: 92 4 3
#18: 100 4 4
#19: 75 4 2
#20: 48 4 1
您也可以在dplyr
和基数R中进行相同的操作>
library(dplyr)
dt %>% group_by(id) %>% mutate(total.rank = as.integer(factor(hours)))
和
dt$total.rank <- with(dt, ave(hours, id, FUN = function(x) as.integer(factor(x))))