【问题标题】:How to do look up variable by ID when there are two ID columns and line by line?当有两个 ID 列并逐行时,如何按 ID 查找变量?
【发布时间】:2018-06-12 16:59:06
【问题描述】:

我有一个数据集,将人们匹配在一起,然后根据两个人的分数(以 SD 计算的 PS1 和 PS2)与他们当前的 D 分数之间的绝对差值计算两个人的分数(D1N 和 D2N)( 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,那么代码会查找该人的 id(P1 和 P2)以获得他们之前的 D 分数。因此,例如在数据集的第二行中,我希望 D2 为 1.224745,因为这是他们最近的 D 分数。然后该行的 DN2 将计算为 2.049,然后这将是 D1 中时间 4 的数字。确切的计算在这里并不重要,我只是想举一个更简单的例子,因为主要问题是如何得到当 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 岁的人是同一个人列)。

有什么方法可以做到这一点?感谢您的帮助!

【问题讨论】:

  • 在您的示例中,第二行的 D2N 应该是 1.224745*sqrt(2.8) = 2.049 吗?我不明白如何计算1.93649
  • 对不起,我有更多关于如何进行计算的细节,但我删除了这些细节,试图让问题的重点更加集中,这可能会使一些计算变得混乱。我认为您拥有的数字是正确的,但主要问题是我仍然不知道如何在两列之间匹配 ID。

标签: r statistics


【解决方案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

【讨论】:

  • 那行得通,非常感谢!这是一个很棒的解决方案,我非常感谢所有帮助!再次感谢,抱歉给您带来的麻烦!
猜你喜欢
  • 2021-03-19
  • 1970-01-01
  • 2021-07-05
  • 2014-11-23
  • 2016-11-13
  • 2016-10-31
  • 1970-01-01
  • 2017-09-12
  • 2017-09-10
相关资源
最近更新 更多