【问题标题】:Ignore Max Value in Mean Calculation in R忽略 R 中平均值计算中的最大值
【发布时间】:2020-01-15 16:08:45
【问题描述】:

我有以下示例 df,来自 20m 冲刺测试运动员的分段时间。他们做了 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 试验并平均其他试验。

【问题讨论】:

  • 到目前为止你尝试了什么?
  • 老实说,我有点迷失了从哪里开始。我还不是很擅长R。例如,我知道如何使用 apply: apply(df[,c("0_20m_1",​​ "0_20m_2", "0_20m_3")], 1, max) 来定位最大值。这将返回我想要过滤掉的最大值,但我如何将它们“连接”到同一试验的 0_10m 和 10_20m?我想我需要让它成为 TRUE/FALSE,而不是先返回值。那么我可以使用 if 语句吗?即如果为 TRUE,则不包含在均值函数中。

标签: r filter max multiple-columns mean


【解决方案1】:
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)

【讨论】:

  • 我不认为你想要desc(time) b/c 你想要两个最快时间的平均值。
  • 所以,我将最高的一个排列到最低的一个,然后选择两个第一行并计算平均值。
  • 对,但最快的时间是最小的时间而不是最大的时间
  • 是的,对不起,所以你只需要删除函数desc,你就得到了你想要的。对不起。
  • 我觉得你们俩真的很亲近! emillman,有没有改变你的解决方案,以便说试验是最后一次(0_20m)最慢的,它从平均计算中消除了整个试验。因为运动员可能有较慢的 0_10m 时间,但弥补了这一点,并在同一试验中拥有快速的 0_20m 时间。因此,0_20m 时间决定了其他拆分是否包含在平均值中,尽管该试验中的拆分时间是否比另一个试验快。我不确定这是否有意义!
【解决方案2】:

首先创建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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-19
    • 2020-12-19
    • 2016-11-04
    • 1970-01-01
    相关资源
    最近更新 更多