我为精英高山滑雪运动员创造了一个数据框架,用于跨越四年的世界杯赛。我正在使用dplyr并按比赛ID对比赛进行分组,由运动员按升序排列比赛结果(从头到尾),并将完成时间转换为分钟。
我现在想要创建一个名为Percent.From.Winning.Time的新变量,该变量将使每个完成时间相对于该特定比赛的获胜时间(即第一名终结者最终得到的值为100,并且休息时获胜时间的百分比小于100。例如,假设某场比赛的获胜时间为120秒,而第二名的比赛时间为121秒。我会计算:[1 - ((121-120)/ 120)] * 100 = 99.16。
请注意,我还指定了非完成时间(例如运动员被取消资格或未完成)作为NA。
以下是一些示例数据:
Raceid=c(1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2)
Athleteid=c(45, 21, 56, 64, 10, 76, 88, 91, 23, 13, 123, 2, 87, 91)
Position = c(1, 2, 3, 4, 5, NA, NA, 1, 2, 3, 4, NA, NA, NA)
Timetot3= c(144, 143, 142, 141, 140, NA, NA, 123, 122, 121, 120, NA, NA, NA)
WC.race.results=cbind(Raceid, Athleteid, Position, Timetot3)
有没有人有关于如何在dplyr中编写函数来生成这个新变量Percent.From.Winning.Time的建议或解决方案?
非常感谢您的考虑。
马特
答案 0 :(得分:3)
这是一个data.table
解决方案:
library(data.table)
setDT(WC.race.results)[
,wt:=(1-(Timetot3-in(Timetot3,na.rm=TRUE))/min(Timetot3,na.rm=TRUE))*100,
Raceid]
# Raceid Athleteid Position Timetot3 wt
# 1: 1 45 1 144 97.14286
# 2: 1 21 2 143 97.85714
# 3: 1 56 3 142 98.57143
# 4: 1 64 4 141 99.28571
# 5: 1 10 5 140 100.00000
# 6: 1 76 NA NA NA
# 7: 1 88 NA NA NA
# 8: 2 91 1 123 97.50000
# 9: 2 23 2 122 98.33333
# 10: 2 13 3 121 99.16667
# 11: 2 123 4 120 100.00000
# 12: 2 2 NA NA NA
# 13: 2 87 NA NA NA
# 14: 2 91 NA NA NA
答案 1 :(得分:3)
使用dplyr的一种方法是;
group_by(mydf, Raceid) %>%
mutate(Percent = (1 - (Timetot3 - min(Timetot3, na.rm = TRUE)) / min(Timetot3, na.rm = TRUE)) * 100)
# Raceid Athleteid Position Timetot3 Percent
#1 1 45 1 144 97.14286
#2 1 21 2 143 97.85714
#3 1 56 3 142 98.57143
#4 1 64 4 141 99.28571
#5 1 10 5 140 100.00000
#6 1 76 NA NA NA
#7 1 88 NA NA NA
#8 2 91 1 123 97.50000
#9 2 23 2 122 98.33333
#10 2 13 3 121 99.16667
#11 2 123 4 120 100.00000
#12 2 2 NA NA NA
#13 2 87 NA NA NA
#14 2 91 NA NA NA
DATA
mydf <- data.frame(Raceid=c(1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2),
Athleteid=c(45, 21, 56, 64, 10, 76, 88, 91, 23, 13, 123, 2, 87, 91),
Position = c(1, 2, 3, 4, 5, NA, NA, 1, 2, 3, 4, NA, NA, NA),
Timetot3= c(144, 143, 142, 141, 140, NA, NA, 123, 122, 121, 120, NA, NA, NA))
答案 2 :(得分:0)
这是更长,但至少是无包装解决方案:
WC.race.results=data.frame(Raceid, Athleteid, Position, Timetot3)
results.split <- by(WC.race.results, WC.race.results$Raceid, function(race) {
win <- min(race$Timetot3, na.rm=TRUE)
cbind(race, wt=(1-((race$Timetot3-win)/race$Timetot3))*100)
})
WC.race.results <- do.call(rbind, results.split)
我非常确定有一种方法可以改善这一点,可能使用dplyr
本身,但我认为这是一个开始。
修改强>
已经有一个dplyr
答案了,无论如何我都会离开我的。