【问题标题】:Adding mean() column with multiple filters throughout dataframe in R在 R 中的整个数据框中添加带有多个过滤器的 mean() 列
【发布时间】:2020-04-16 23:10:19
【问题描述】:

R 新手,正在将其用于数据框中的一些 NFL 分析,其中相关列如下所示:

  1. 兰迪·莫斯 12.9 2000
  2. 兰迪·莫斯 21.6 2000
  3. 兰迪莫斯 4.0 2000
  4. 兰迪·莫斯 44.7 2000
  5. 兰迪·莫斯 25.8 2000
  6. 兰迪·莫斯 12.9 2000

这不是一个列表,它是一个数据框,其中玩家(“fname.1”)每场比赛的幻想统计数据(“fp3”)和比赛年份(“year”)是有问题的列。该数据包括 2000 年至 2019 年的所有年份。

我想添加一个列,该列是该玩家当年所有幻想结果的平均值。所以,我在示例数据中想要的输出(如果兰迪莫斯只玩了 6 场比赛)将为每个条目添加一列平均值,如下所示:

  1. 兰迪·莫斯 12.9 2000 16.98333
  2. 兰迪·莫斯 21.6 2000 16.98333
  3. 兰迪莫斯 4.0 2000 16.98333
  4. 兰迪·莫斯 44.7 2000 16.98333
  5. 兰迪·莫斯 25.8 2000 16.98333
  6. 兰迪·莫斯 12.9 2000 16.98333

我在使用简单的 group_by() 和 summarise() 公式时遇到了麻烦,因为每年每个玩家都需要不同的平均值。我写了一个 for 循环,它创建了一个包含我需要的信息的列表,但我不确定如何将它添加到原始数据中,或者是否有更简单的方法来完成这个......

mean_fantasy <- list()
 for(y in 2000:2019) {
     mean_fantasy[[y]] <- offense_test %>%
         filter(year == y) %>%
         group_by(fname.1) %>%
         summarize(mean_fp3 = sum(fp3)/n(), games = n(), year = sum(year)/n())     
      }

对 R 和这个论坛非常陌生,所以希望这个问题/格式有意义

【问题讨论】:

    标签: r


    【解决方案1】:

    只需使用ave() 函数即可得到您正在寻找的结果,即每位玩家每年的平均值。

       fp3 <- rnorm(20,20,5)
       player <- rep(c(LETTERS)[1:4], each = 5)
       year <- as.factor(rep(seq(2015,2016, by = 1), 10))
    
       df <- data.frame(player,fp3,year)
    
       df$mean.player.year <- ave(df$fp3, df[,c('player', 'year')], FUN = mean)
    
       # And for the desired output view...  
       df <- df[order(df$player,df$year),]
    
     > df
       player       fp3 year mean.player.year
    1       A 20.658824 2015         14.36088
    3       A 19.842985 2015         14.36088
    5       A  2.580835 2015         14.36088
    2       A 12.571649 2016         14.33038
    4       A 16.089108 2016         14.33038
    7       B 34.268847 2015         27.21018
    9       B 20.151507 2015         27.21018
    6       B  9.363759 2016         15.10290
    8       B 19.686929 2016         15.10290
    10      B 16.257998 2016         15.10290
    11      C 25.823640 2015         21.57919
    13      C 17.753304 2015         21.57919
    15      C 21.160641 2015         21.57919
    12      C 20.878661 2016         23.27219
    14      C 25.665711 2016         23.27219
    17      D 22.621288 2015         22.81370
    19      D 23.006116 2015         22.81370
    16      D 25.508619 2016         19.37231
    18      D 13.923885 2016         19.37231
    20      D 18.684435 2016         19.37231
    

    【讨论】:

      【解决方案2】:

      我们可以使用transmutemap

      library(dplyr)
      library(purrr)
      library(stringr)
      out <-  map_dfc(2000:2019, ~ offense_test %>%
                           filter(year == .x) %>%
                           group_by(fname.1) %>%
                           transmute(!! str_c('mean_fp3_', .x) :=  sum(fp3)/n(),
                                     !! str_c('games_', .x) := n(), 
                                     !! str_c('year_', .x)  := sum(year)/n())) %>%
              bind_cols(offense_test, .)
      

      如果我们需要单个 mean 列,那么我们不需要循环,在 group_by 中也使用“年份”,然后使用 mutate 创建列

      offense_test %>%
           group_by(fname.1, year) %>%
           mutate(mean_fp3 = mean(fp3), games = n())
      

      【讨论】:

        【解决方案3】:

        感谢大家的回答,因为它更简单,所以选择了 Roasty's。可以验证它是否有效

        【讨论】:

          猜你喜欢
          • 2021-09-09
          • 2020-08-02
          • 1970-01-01
          • 2021-11-27
          • 1970-01-01
          • 2020-10-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多