我按照日期对球员进行了一系列网球排名
date <- as.Date(c("1973-08-23","1973-09-13","1973-09-26","1973-10-15","1973-10-31"))
ranking <- c(1,2,3,3,1)
df <- data.frame(date,ranking)
date ranking
1 1973-08-23 1
2 1973-09-13 2
3 1973-09-26 3
4 1973-10-15 3
5 1973-10-31 1
它们大约每两周一次,但每天都不同
library(lubridate)
wday(df$date) # [1] 5 5 4 2 4
我想根据上面的数据创建一个data.frame(df2),以便每周一次显示排名。结果将是
date ranking
1 1973-08-27 1
2 1973-09-03 1
3 1973-09-10 1
4 1973-09-17 2
5 1973-09-24 2
6 1973-10-01 3
7 1973-10-08 3
8 1973-10-15 3
9 1973-10-22 3
10 1973-10-29 3
11 1973-11-05 1
wday(df2$date) # [1] 2 2 2 2 2 2 2 2 2 2 2
这有点简化,因为所有等级都有PlayerA,PlayerB等
任何帮助非常感谢
答案 0 :(得分:2)
weekly_ranks <- function(df) {
date <- df[,1]
rank <- df[,2]
start <- if(wday(min(date)) <= 2)
{min(date) +2-wday(min(date))
} else {min(date) + 9-wday(min(date))}
end <- max(date)
mondays <- seq(start, end, by=7)
ranks <- match(as.character(cut(mondays, date)), as.character(date))
data.frame(date=c(mondays, end),
ranking=c(rank[ranks], rank[df$date == end]))
}
weekly_ranks(Player_A)
# date ranking
# 1 1973-08-27 1
# 2 1973-09-03 1
# 3 1973-09-10 1
# 4 1973-09-17 2
# 5 1973-09-24 2
# 6 1973-10-01 3
# 7 1973-10-08 3
# 8 1973-10-15 3
# 9 1973-10-22 3
# 10 1973-10-29 3
# 11 1973-10-31 1
对于所有玩家,您可以这样做:
lst <- list(Player_A, Player_B, Player_C)
lapply(lst, weekly_ranks)
答案 1 :(得分:2)
理想的解决方案是data.table
加入roll=Inf
library(data.table)
df1 <- data.table(date=seq.Date(from=as.Date("1973-08-27"), to=as.Date("1973-11-05"), by=7))
setkey(setDT(df), date)
setkey(df1, date)
df[df1, roll=Inf]
# date ranking
# 1: 1973-08-27 1
# 2: 1973-09-03 1
# 3: 1973-09-10 1
# 4: 1973-09-17 2
# 5: 1973-09-24 2
# 6: 1973-10-01 3
# 7: 1973-10-08 3
# 8: 1973-10-15 3
# 9: 1973-10-22 3
#10: 1973-10-29 3
#11: 1973-11-05 1
答案 2 :(得分:1)
您必须创建所需大小的空数据框。然后你创建一个for循环来运行这个新的数据框,并用最新的可用排名填充它。每当有新的排名时,你就会把他带到下一行。
更清楚:
j=1
for(i in 1:length(output[,1])){
if(as.numeric(output[i,1])>as.numeric(input[j,1])){
j=j+1
}
output[i,2:10] = input[j,2:10]
}
其中output
是一个数组,其行数与星期一一样多,列数与玩家数量相同(日期为+1)