R Dataframe 按组滚动测量
R Dataframe Rolling Measures 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 的理想输出。例如,他的第一行的“计数”是 1,因为这是他在数据中的第一年,并且 (1/1)^2=1。对于他的第二行,包括到目前为止的三年(2005、2006、2007),count=(1/3)^2+(2/3)=0.56(假设 2006 年缺少数据,Phelan 还留在芝加哥大火)。对于他的第三行,count=(2/4)^2+(2/4)^2=0.5。对于他的第四行,count=(3/6)^2+(3/6)^2=0.5(假设在缺少数据的 2009 年,Phelan 也留在了 Boston Pant)。
Year Player Club Count
2005 Phelan Chicago Fire 1
2007 Phelan Boston Pant 0.56
2008 Phelan Boston Pant 0.5
2010 Phelan Chicago Fire 0.5
这有点令人费解,但我认为它可以满足您的需求。
使用data.table
:
library(data.table)
library(zoo) # for na.locf(...)
##
expand.df <- setDT(df)[, .(Year=min(Year):max(Year)), by=.(Player)]
expand.df[df, Club:=i.Club, on=.(Player, Year)]
expand.df[, Club:=na.locf(Club)]
expand.df[, cuml.exp:=1:.N, by=.(Player)]
expand.df <- expand.df[expand.df[, .(Player, cuml.exp)], on=.(Player, cuml.exp <= cuml.exp)]
expand.df <- expand.df[, .(Year=max(Year), club.exp=sum(sapply(unique(Club), \(x) sum(Club==x)^2))), by=.(Player, cuml.exp)]
expand.df[, score:=club.exp/cuml.exp^2]
result <- expand.df[df, on=.(Player, Year), nomatch=NULL]
result[, .(Player, Year, Club, cuml.exp, club.exp, score)]
## Player Year Club cuml.exp club.exp score
## 1: Phelan 2005 Chicago Fire 1 1 1.0000000
## 2: Phelan 2007 Boston Pant 3 5 0.5555556
## 3: Phelan 2008 Boston Pant 4 8 0.5000000
## 4: Phelan 2010 Chicago Fire 6 18 0.5000000
## 5: John 2002 New York Jet 1 1 1.0000000
## 6: John 2006 New York Jet 5 25 1.0000000
## 7: John 2007 Atlanta Elephant 6 26 0.7222222
## 8: John 2009 Los Angeles Eagle 8 30 0.4687500
因此,这会扩展您的 df
以包括每个球员每年一行,然后在适当的年份重新加入俱乐部,然后根据您的描述填补空白。然后我们计算每个玩家的累计经验年数。
下一位是复杂的部分:我们需要进一步扩展,以便对于 player 和 cuml.exp 的每个组合,我们拥有到该点为止的所有行。 join on=.(Player, cuml.exp <= cuml.exp)
就是这样做的。然后我们可以按球员统计每个俱乐部的实例数,cuml.exp得到你得分的分子。
然后我们计算分数,去掉多余的年份和多余的列。
请注意,这假设您拥有 R 4.1+。如果不是,请将 \(x)...
替换为 function(x)...
.
我有一个数据框如下所示(真实数据有更多人):
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 的理想输出。例如,他的第一行的“计数”是 1,因为这是他在数据中的第一年,并且 (1/1)^2=1。对于他的第二行,包括到目前为止的三年(2005、2006、2007),count=(1/3)^2+(2/3)=0.56(假设 2006 年缺少数据,Phelan 还留在芝加哥大火)。对于他的第三行,count=(2/4)^2+(2/4)^2=0.5。对于他的第四行,count=(3/6)^2+(3/6)^2=0.5(假设在缺少数据的 2009 年,Phelan 也留在了 Boston Pant)。
Year Player Club Count
2005 Phelan Chicago Fire 1
2007 Phelan Boston Pant 0.56
2008 Phelan Boston Pant 0.5
2010 Phelan Chicago Fire 0.5
这有点令人费解,但我认为它可以满足您的需求。
使用data.table
:
library(data.table)
library(zoo) # for na.locf(...)
##
expand.df <- setDT(df)[, .(Year=min(Year):max(Year)), by=.(Player)]
expand.df[df, Club:=i.Club, on=.(Player, Year)]
expand.df[, Club:=na.locf(Club)]
expand.df[, cuml.exp:=1:.N, by=.(Player)]
expand.df <- expand.df[expand.df[, .(Player, cuml.exp)], on=.(Player, cuml.exp <= cuml.exp)]
expand.df <- expand.df[, .(Year=max(Year), club.exp=sum(sapply(unique(Club), \(x) sum(Club==x)^2))), by=.(Player, cuml.exp)]
expand.df[, score:=club.exp/cuml.exp^2]
result <- expand.df[df, on=.(Player, Year), nomatch=NULL]
result[, .(Player, Year, Club, cuml.exp, club.exp, score)]
## Player Year Club cuml.exp club.exp score
## 1: Phelan 2005 Chicago Fire 1 1 1.0000000
## 2: Phelan 2007 Boston Pant 3 5 0.5555556
## 3: Phelan 2008 Boston Pant 4 8 0.5000000
## 4: Phelan 2010 Chicago Fire 6 18 0.5000000
## 5: John 2002 New York Jet 1 1 1.0000000
## 6: John 2006 New York Jet 5 25 1.0000000
## 7: John 2007 Atlanta Elephant 6 26 0.7222222
## 8: John 2009 Los Angeles Eagle 8 30 0.4687500
因此,这会扩展您的 df
以包括每个球员每年一行,然后在适当的年份重新加入俱乐部,然后根据您的描述填补空白。然后我们计算每个玩家的累计经验年数。
下一位是复杂的部分:我们需要进一步扩展,以便对于 player 和 cuml.exp 的每个组合,我们拥有到该点为止的所有行。 join on=.(Player, cuml.exp <= cuml.exp)
就是这样做的。然后我们可以按球员统计每个俱乐部的实例数,cuml.exp得到你得分的分子。
然后我们计算分数,去掉多余的年份和多余的列。
请注意,这假设您拥有 R 4.1+。如果不是,请将 \(x)...
替换为 function(x)...
.