当有两个ID列并逐行时,如何通过ID查找变量?

时间:2018-06-12 16:59:06

标签: r statistics

我有一个匹配人在一起的数据集,然后根据两个人的得分(按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列)。

这样做的方法是什么?谢谢你的帮助!

1 个答案:

答案 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