忽略 R 中均值计算中的最大值

Ignore Max Value in Mean Calculation in R

我有以下来自 20 米短跑测试运动员的 df 样本。他们做了 3 次试验。我想为每个拆分创建新的列,平均他们的两个最快的试验(放弃最慢的试验)。

这是 df 的示例:

    Athlete 0_10m_1 10_20m_1 0_20m_1 0_10m_2 10_20m_2 0_20m_2 0_10m_3 10_20m_3 0_20m_3
1 Athlete 1   2.005    1.320   3.325   1.904    1.306   3.210   1.993    1.316   3.309
2 Athlete 2   1.967    1.383   3.350   1.931    1.391   3.322   2.005    1.399   3.404
3 Athlete 3   2.008    1.381   3.389   2.074    1.365   3.439   2.047    1.408   3.455
4 Athlete 4   1.817    1.286   3.103   1.924    1.285   3.209      NA       NA      NA

最终结果将是 3 个新列,其中包含 2 个最快试验的平均值(基于 0_20m 时间)("Avg_0_10m"、"Avg_10_20m"、Avg_0_20m")。理想情况下,解决方案足够强大,可以处理 NA 值,因为数据集中会有一些值。

关于如何处理这个问题有什么建议吗?我不确定如何能够过滤掉具有相关分段时间的最慢 0_20m 试验并平均其他试验。

library(tidyverse)

x <- read.table(text=" Athlete 0_10m_1 10_20m_1 0_20m_1 0_10m_2 10_20m_2 0_20m_2 0_10m_3 10_20m_3 0_20m_3
'Athlete 1'   2.005    1.320   3.325   1.904    1.306   3.210   1.993    1.316   3.309
'Athlete 2'   1.967    1.383   3.350   1.931    1.391   3.322   2.005    1.399   3.404
'Athlete 3'   2.008    1.381   3.389   2.074    1.365   3.439   2.047    1.408   3.455
'Athlete 4'  1.817    1.286   3.103   1.924    1.285   3.209      NA       NA      NA", header=TRUE, check.names=FALSE)


x %>%
  gather(trial,time,-Athlete) %>%
  separate(trial, sep = "(?<=m)_", into = c("trial_time", "trial_try")) %>%
  group_by(Athlete, trial_time) %>%
  group_split() %>%
  purrr::map(function(x) {
    x %>%
      arrange(time) %>%
      group_by(Athlete, trial_time) %>%
      summarise(time_avg = mean(time[1:2], na.rm = TRUE))
  }) %>%
  bind_rows() %>%
  spread(trial_time, time_avg)

首先创建data.frame。

x <- read.table(text="x Athlete 0_10m_1 10_20m_1 0_20m_1 0_10m_2 10_20m_2 0_20m_2 0_10m_3 10_20m_3 0_20m_3
1 Athlete 1   2.005    1.320   3.325   1.904    1.306   3.210   1.993    1.316   3.309
2 Athlete 2   1.967    1.383   3.350   1.931    1.391   3.322   2.005    1.399   3.404
3 Athlete 3   2.008    1.381   3.389   2.074    1.365   3.439   2.047    1.408   3.455
4 Athlete 4   1.817    1.286   3.103   1.924    1.285   3.209      NA       NA      NA", header=T, check.names=F)


x %>% select(-x) %>% 
   gather("split", "time", -Athlete) %>% 
   mutate(split = gsub("_\d$","", split)) %>% 
   group_by(Athlete, split) %>% 
   arrange(time) %>% 
   slice(1:2) %>% 
   summarize(Avg = mean(time))
# A tibble: 12 x 3
# Groups:   Athlete [4]
#   Athlete split    Avg
#     <int> <chr>  <dbl>
# 1       1 0_10m   1.95
# 2       1 0_20m   3.26
# 3       1 10_20m  1.31
# 4       2 0_10m   1.95
# 5       2 0_20m   3.34
# 6       2 10_20m  1.39
# 7       3 0_10m   2.03
# 8       3 0_20m   3.41
# 9       3 10_20m  1.37
#10       4 0_10m   1.87
#11       4 0_20m   3.16
#12       4 10_20m  1.29