使用等级顺序计算 R 中的死亡率数据

Using rank order to calculate death rate data in R

我想对每个个人 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")

您可以将 hours 转换为 factor,然后将 integer 转换为 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 和 base 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))))

我们可以使用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]