Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 有没有一种方法可以创建一个依赖于一组复杂(乒乓)规则的变量,而不使用循环?_R_Loops - Fatal编程技术网

R 有没有一种方法可以创建一个依赖于一组复杂(乒乓)规则的变量,而不使用循环?

R 有没有一种方法可以创建一个依赖于一组复杂(乒乓)规则的变量,而不使用循环?,r,loops,R,Loops,我在做一个乒乓球数据项目。我有一个很大的数据集,包括乒乓球比赛每次发球的记录数据,其中一个变量表示谁赢得了哪一分,一个变量表示谁发球开始比赛,但没有变量表示谁发球。乒乓球的规则,或者至少,我们的内部规则允许我推断出最后一个变量——发球每五次就停止一次,一旦一名球员到达比赛点,另一名球员将接手发球,直到他们到达比赛点。以下面的比赛为例,在这场比赛中,直到20比20,才有人破发。在这场比赛中,球员1连续赢了两分,以22比20领先21,以2胜 WonServe <- "Player1" Serv

我在做一个乒乓球数据项目。我有一个很大的数据集,包括乒乓球比赛每次发球的记录数据,其中一个变量表示谁赢得了哪一分,一个变量表示谁发球开始比赛,但没有变量表示谁发球。乒乓球的规则,或者至少,我们的内部规则允许我推断出最后一个变量——发球每五次就停止一次,一旦一名球员到达比赛点,另一名球员将接手发球,直到他们到达比赛点。以下面的比赛为例,在这场比赛中,直到20比20,才有人破发。在这场比赛中,球员1连续赢了两分,以22比20领先21,以2胜

WonServe <- "Player1"
Serve <- seq_len(42)
MatchNum <- rep(1, 42)
Player1Points <- c(1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1,1)
Player2Points <- c(0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,0,0)
ServingPlayer <- c(1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,NA,NA)
df <- as.data.frame(cbind(Serve, Player1Points, Player2Points, ServingPlayer, MatchNum))

现在,我知道前40次发球是谁发球,但之后事情就变得棘手了。球员1以20比20先发球,因为他最初赢得了发球权,现在又回到了他手中。然而,一旦他以21-20领先,球员2将接手发球。我希望在我的数据中建立这一规则的模型,以找出谁在发球超过40次后的每一次发球中发球。使用循环时,这可能如下所示:

for(i in 41:length(df$ServingPlayer)) {

  if(i == 41) {

    if(WonServe == "Player1") {df$ServingPlayer <- 1} else if(WonServe == "Player2") {df$ServingPlayer <- 0}

  } else if(i > 41) {

    if(cumsum(df$Player1Points[i]) > cumsum(df$Player2Points[i])) {

      df$ServingPlayer[i] <- 0

    } else if(cumsum(df$Player1Points[i]) < cumsum(df$Player2Points[i])) {

      df$ServingPlayer[i] <- 1

    } else if(cumsum(df$Player1Points[i]) == cumsum(df$Player2Points[i])) {

      df$ServingPlayer[i] <- df$ServingPlayer[i-1]

    }

  }

}
我的问题是,我们有一个庞大的数据集,其中包括数百个游戏。如果我要在整个数据集上使用它,我想我必须在一个循环中创建一个循环,将这个循环应用到数据集中df$MatchNum的每一个值——这会变得非常缓慢

总的来说,有没有一种方法可以在不使用循环的情况下应用这种逻辑? 如果没有,是否至少有一种方法可以将此单个循环应用于包含许多不同匹配项的长数据集,而不使用大型循环?
您可以创建比所需长度更长的发球指示器向量,然后仅提取所需长度:

 c(rep( rep(1:0, each=5), 4), rep(Player1Points[1]:Player2Points[1], times=20) )[ 1:length(Player1Points)]
#-------
 [1] 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 1 1
[33] 1 1 1 0 0 0 0 0 1 0

为什么我们要在这里避免循环?我不确定我是否理解动机。您的示例输入所需的输出是什么?如果这才是真正的问题所在,那么拥有一个包含多个匹配项的数据集就更好了。这样就可以检验可能的解决方案。既然他最初赢得了发球权?这是否意味着赢得第一分的球员是以20-20发球的球员?一般来说:对于最后发球的状态和获胜的一系列更新的问题,可以使用Reduce避免显式使用For循环。不过,通常需要一些聪明