R Dataframe 加权平均值(按组)

R Dataframe Weighted Averages by Group

我有一个数据框如下所示(真实数据有更多人):

Year   Player    Club
2005   Phelan    Chicago Fire 
2007   Phelan    Boston Pant
2008   Phelan    Boston Pant
2010   Phelan    Chicago Fire  
2002   John      New York Jet
2006   John      New York Jet
2007   John      Atlanta Elephant
2009   John      Los Angeles Eagle

我想计算每个球员的球员水平衡量标准(计数),以捕捉一个人经历过的俱乐部的加权数量。公式为(经历时长1/总年数)^2+(经历时长2/总年数)^2+……

下面是示例数据的理想输出。例如,Phelan 的“计数”等于 (2/6)^2+(3/6)^2+(1/6)^2=0.389(假设在缺少数据的 2006 年,Phelan 留在了 Chicago Fire . 并假设在 2009 年,即缺少数据,Phelan 留在了 Boston Pant。

Player    Count
Phelan    0.389
John      0.469

在这里,我删掉了重复 Player-Club 年。如果球员的数据以同一俱乐部的重复结尾,这可能会给出错误的结果,但我不能立即想到更好的方法。

df %>%
  group_by(Player) %>%
  filter(Club != lag(Club, default = "")) %>%
  mutate(yrs = coalesce(Year - lag(Year), 1)) %>%
  summarize(Count = sum((yrs / sum(yrs))^2))


 A tibble: 2 × 2
  Player Count
  <chr>  <dbl>
1 John   0.469
2 Phelan 0.389

这是另一个 tidyverse 选项(虽然比@JonSpring 的好回答更冗长),我在其中填写缺失年份的系列,并假设在缺失年份中玩家停留在同一个地方.然后,我为每个 Player 的连续值创建唯一的组,然后获取观察数,最后应用公式。

library(tidyverse)

df %>%
  group_by(Player) %>%
  complete(., Year = full_seq(Year, period = 1)) %>%
  fill(Club, .direction = "down") %>%
  group_by(Player, grp = with(rle(Club), rep(seq_along(lengths), lengths))) %>%
  summarise(club_sum = sum(n())) %>%
  summarise(count = sum((club_sum / sum(club_sum)) ^ 2))

输出

  Player count
  <chr>  <dbl>
1 John   0.469
2 Phelan 0.389