我有一个匹配人在一起的数据集,然后根据两个人的得分(按SD计算的PS1和PS2)及其他人的绝对差值计算两个人的得分(D1N和D2N)目前的D分(D1和D2)。我设置了数据集,这样一个人第一次出现在人们之间的匹配(作为P1或P2)时,他们的D分数默认为1(我在数据集中有一个时间变量来执行此操作)。下面是一个更小,更简单的数据集的示例。
dataset <- structure(list(Time = 1:5, P1 = c(1L, 3L, 3L, 2L, 5L), P2 = c(2L,
2L, 5L, 1L, 4L), PS1 = c(1, -0.3, -0.3, 2.5, 0.5), PS2 = c(2.5,
2.5, 0.5, 1, -1), SD = c(1.5, 2.8, 0.8, 1.5, 1.5), D1 = c(1L,
1L, NA, NA, NA), D2 = c(1L, NA, 1L, NA, 1L), D1N = c(1.224744871,
NA, NA, NA, NA), D2N = c(1.224744871, NA, NA, NA, NA)), .Names = c("Time",
"P1", "P2", "PS1", "PS2", "SD", "D1", "D2", "D1N", "D2N"), class = "data.frame", row.names = c(NA,
-5L))
我要做的是逐行计算DN1和DN2,这样如果D1和D2不是1,那么代码会查找该人的身份(P1和P2)以获得他们之前的D得分。因此,例如在数据集的第二行中,我希望D2为1.224745,因为这是他们最近的D分数。然后该行的DN2将计算为2.049,然后这将是时间4中D1的数字。精确的计算在这里并不重要我只是想提供一个更简单的例子,因为主要问题是如何当id超过2列时,根据id来获取后续行中的数字。
我知道这里有一行代码,如下所示:
for (row in 1:nrow(dataset)){
#code here that will pull previous D value based on ID across columns if D is not 1
dataset$D1N <- dataset$D1*sqrt(dataset$SD)
dataset$D2N <- dataset$D2*sqrt(dataset$SD)
}
但我不知道如何跨两列进行ID查找。
要清楚P1和P2只是两列来匹配人,但两列中的ID仍然是唯一ID(如果P1列中的某人是5,那么P2中的人是5列)。
这样做的方法是什么?谢谢你的帮助!
答案 0 :(得分:1)
这是一个可能的解决方案,它可以为按降序排列的玩家ID创建单独的查找表来工作
library(reshape2)
#create melted table to lookup player ID
players<-melt(dataset[,1:3], id.vars="Time", value.name = "player_id")
players<-players[order(players$Time, decreasing = TRUE),]
players$variable<-gsub("P", "",players$variable)
players$lookup_col<-paste0("D", players$variable, "N")
players
# Time variable player_id lookup_col
#5 5 1 5 D1N
#10 5 2 4 D2N
#4 4 1 2 D1N
#9 4 2 1 D2N
#3 3 1 3 D1N
#8 3 2 5 D2N
#2 2 1 3 D1N
#7 2 2 2 D2N
#1 1 1 1 D1N
#6 1 2 2 D2N
然后,您可以遍历数据集,填写NA并计算D1N和D2N
for (row in 2:nrow(dataset)){
p1<-dataset[row,"P1"]
p2<-dataset[row,"P2"]
D1<-dataset[row,"D1"]
D2<-dataset[row,"D2"]
#if D1 or D2 is blank, lookup the last game by that ID in the "players" dataframe
#and retrieve that row from the dataset
if(is.na(D1)) {
pl_row<-players[which(players$Time<row & players$player_id==p1)[1],]
D1<-dataset[pl_row$Time, pl_row$lookup_col]
dataset[row, "D1"]<-D1
}
if(is.na(D2)) {
pl_row<-players[which(players$Time<row & players$player_id==p2)[1],]
D2<-dataset[pl_row$Time, pl_row$lookup_col]
dataset[row, "D2"]<-D2
}
dataset[row, "D1N"] <- D1*sqrt(dataset[row, "SD"])
dataset[row, "D2N"] <- D2*sqrt(dataset[row, "SD"])
}
dataset
# Time P1 P2 PS1 PS2 SD D1 D2 D1N D2N
# 1 1 1 2 1.0 2.5 1.5 1.0000000 1.000000 1.224745 1.2247449
# 2 2 3 2 -0.3 2.5 2.8 1.0000000 1.224745 1.673320 2.0493902
# 3 3 3 5 -0.3 0.5 0.8 1.6733201 1.000000 1.496663 0.8944272
# 4 4 2 1 2.5 1.0 1.5 2.0493902 1.224745 2.509980 1.5000000
# 5 5 5 4 0.5 -1.0 1.5 0.8944272 1.000000 1.095445 1.2247449