在R中为连续的TRUE创建新列

时间:2018-04-24 11:27:54

标签: r

我想创建新列,如果连续获胜的数量为2,则为3,则为TRUE。所以我希望第3,6,7,8行在名为" twoconswins&#的新列中为TRUE 34;并且第7行,第8行在名为" threeconswins"等等。这样做的最佳方式是什么?

>         id        date team teamscore opponent opponentscore home   win
>9         9 2005-10-05  DET         5      STL             1    1  TRUE
>38       38 2005-10-09  DET         6      CAL             3    1  TRUE
>48       48 2005-10-10  DET         2      VAN             4    1 FALSE
>88       88 2005-10-17  DET         3      SJS             2    1  TRUE
>110     110 2005-10-21  DET         3      ANA             2    1  TRUE
>148     148 2005-10-27  DET         5      CHI             2    1  TRUE
>179     179 2005-11-01  DET         4      CHI             1    1  TRUE
>194     194 2005-11-03  DET         3      EDM             4    1 FALSE
>212     212 2005-11-05  DET         1      PHO             4    1 FALSE

2 个答案:

答案 0 :(得分:1)

我假设第1行应该是标题,因此实际上第2,第5,第6和第7行应评估为" twoconswins"以及第6行和第7行为" threeconswins&#34 ;

你可以这样做:

library(data.table)
df$twoconswins <-  (df$win & shift(df$win, 1, NA)) == TRUE
df$threeconswins <- (df$win & shift(df$win, 1, NA) & shift(df$win, 2, NA)) == TRUE

我认为这可能会更加矢量化,特别是如果连续50次获胜也是如此,并且您也想为此创建列。

答案 1 :(得分:1)

如果您想自动创建新列,如果有时会发生连续500次胜利,您可以这样做:

df <- read.table(text =
                      'id   date     team teamscore opponent opponentscore home   win
             9         9 2005-10-05  DET         5      STL             1    1  TRUE
             38       38 2005-10-09  DET         6      CAL             3    1  TRUE
             48       48 2005-10-10  DET         2      VAN             4    1  FALSE
             88       88 2005-10-17  DET         3      SJS             2    1  TRUE
             110     110 2005-10-21  DET         3      ANA             2    1  TRUE
             148     148 2005-10-27  DET         5      CHI             2    1  TRUE
             179     179 2005-11-01  DET         4      CHI             1    1  TRUE
             194     194 2005-11-03  DET         3      EDM             4    1 FALSE
             212     212 2005-11-05  DET         1      PHO             4    1 FALSE',
 header = TRUE)



rles <- data.frame(values = c(rle(df$win)$values), 
                   lengths = c(rle(df$win)$lengths))

maxconwins <-  max(rles[rles$values == TRUE,]) 

for(x in 1: maxconwins){
  x <- seq(1,x)
  partialstring <- paste("shift(df$win,", x, ",NA)", collapse = " & ")
  fullstring <- paste0("df$nr", max(x), "conswins <-  (", partialstring, ") == TRUE")
  eval(parse(text = fullstring))
}

df[1:maxconwins,9:12][upper.tri(df[1:maxconwins,9:12], diag = TRUE)] <- NA

   > df[,8:12]
      win nr1conswins nr2conswins nr3conswins nr4conswins
9    TRUE          NA          NA          NA          NA
38   TRUE        TRUE          NA          NA          NA
48  FALSE        TRUE        TRUE          NA          NA
88   TRUE       FALSE       FALSE       FALSE          NA
110  TRUE        TRUE       FALSE       FALSE       FALSE
148  TRUE        TRUE        TRUE       FALSE       FALSE
179  TRUE        TRUE        TRUE        TRUE       FALSE
194 FALSE        TRUE        TRUE        TRUE        TRUE
212 FALSE       FALSE       FALSE       FALSE       FALSE

BTW,我只添加了最后一行因为(FALSE&amp; TRUE&amp; TRUE&amp; NA)== TRUE评估为FALSE,而您可能希望这些单元格为NA。我刚刚通过将对称子矩阵的上三角形设置为NA来确定这一点。为了便于阅读,我在这里手动添加了第9和第12列,但如果您愿意,也可以指定具有功能的列号。

更新: 当使用Frank建议的Reduce()函数时,你可以为循环而不是上面的方法执行此操作:

for(x in 1: maxconwins){
 x <- seq(1,x)
 eval(parse(text = paste0("df$nr", max(x), "conswins <- (Reduce(`&`, shift(df$win, 1:", max(x), "))) == TRUE")))
 }