【问题标题】:Calculating percent from winning time in data frame of race results for elite athletes计算精英运动员比赛结果数据框架中获胜时间的百分比
【发布时间】:2015-03-29 22:30:02
【问题描述】:

我创建了一个数据框架,其中包含四年期间所有世界杯比赛的精英高山滑雪者的比赛结果。我正在使用 dplyr 并按 Race 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,是否有人有建议或解决方案?

非常感谢您的考虑。

马特

【问题讨论】:

    标签: r dplyr percentage


    【解决方案1】:

    使用 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
    

    数据

    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))
    

    【讨论】:

    • 这个解决方案效果很好。它很容易使用,因为我正在使用各种 dplyr 函数构建表格。如果您正在使用 dplyr,这将是计算此类性能指标的好方法。
    【解决方案2】:

    这里是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
    

    【讨论】:

      【解决方案3】:

      这是一个更长但至少无需打包的解决方案:

      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 的回答了,反正我会离开的。

      【讨论】:

      • lapply-ing on split 数据等价于by
      • 我不熟悉,谢谢。我应该使用by(WC.race.results, WC.race.results$Raceid, function(race)...吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-13
      • 2021-12-11
      • 2021-03-18
      • 2017-04-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多