gib*_*z00 6 r rank dplyr data.table
以下是我的dataframe/data.table的样子.该rank列是我想要的计算字段.
library(data.table)
df <- fread('
Name Score Date Rank
John 42 1/1/2018 3
Rob 85 12/31/2017 2
Rob 89 12/26/2017 1
Rob 57 12/24/2017 1
Rob 53 08/31/2017 1
Rob 72 05/31/2017 2
Kate 87 12/25/2017 1
Kate 73 05/15/2017 1
')
df[,Date:= as.Date(Date, format="%m/%d/%Y")]
Run Code Online (Sandbox Code Playgroud)
我试图在30天窗口内的数据中计算每个学生在每个给定时间点的等级.为此,我需要在给定的时间点获取所有学生的最新分数,然后通过等级函数.
在第1行,为的1/1/2018,John已经在过去30天的窗口,两个竞争对手:罗布与最近的得分85在12/31/2017和凯特与最近的得分87在12/25/2017和这两个日期都落在内1/1/2018 - 30天的窗口.约翰3得分最低42.如果只有一名学生date(at a given row) - 30 day window,则排名为1.
在第3行,日期是12/26/2017.所以Rob的得分12/26/2017是89.只有一个案例的另一名学生落入时间窗口,12/26/2017 - 30这是87凯特最近的得分()12/25/2017.因此,在时间窗口内(12/26/2017) - 30,Rob的得分89高于Kate的得分,87因此Rob获得了排名1.
我正在考虑使用这里的框架在过去的365天窗口中执行运行总计的有效方法,但是在使用排名之前努力想到一种方法来获取所有学生在给定时间点的所有最近得分.
这似乎有效:
ranks = df[.(d_dn = Date - 30L, d_up = Date), on=.(Date >= d_dn, Date <= d_up), allow.cart=TRUE][,
.(LatestScore = last(Score)), by=.(Date = Date.1, Name)]
setorder(ranks, Date, -LatestScore)
ranks[, r := rowid(Date)]
df[ranks, on=.(Name, Date), r := i.r]
Name Score Date Rank r
1: John 42 2018-01-01 3 3
2: Rob 85 2017-12-31 2 2
3: Rob 89 2017-12-26 1 1
4: Rob 57 2017-12-24 1 1
5: Rob 53 2017-08-31 1 1
6: Rob 72 2017-05-31 2 2
7: Kate 87 2017-12-25 1 1
8: Kate 73 2017-05-15 1 1
Run Code Online (Sandbox Code Playgroud)
...使用,last因为笛卡尔连接似乎排序,我们想要最新的测量.
更新加入的工作原理
该i.前缀意味着它是从列i在x[i, ...]加入,并指派:=总是在x.所以它正在查找iin的每一行x和找到匹配的位置,将值复制i到x.
另一种有时有用的方法是查找x行i,例如df[, r := ranks[df, on=.(Name,Date), x.r]]在某种情况下x.r仍然来自ranks表(现在位于x相对于连接的位置).
还有......
ranks = df[CJ(Name = Name, Date = Date, unique=TRUE), on=.(Name, Date), roll=30, nomatch=0]
setnames(ranks, "Score", "LatestScore")
# and then use the same last three lines above
Run Code Online (Sandbox Code Playgroud)
我不确定一个与另一个的效率,但我想这取决于名称的数量,测量的频率以及测量天数重合的频率.