繁体   English   中英

为R中的连续TRUE创建新列

[英]Creating new columns for consecutive TRUEs in R

我想创建一个新列,如果连续获胜的次数是两个,三个等,则为TRUE。所以我希望第3、6、7、8行在名为“ twoconswins”的新列中为TRUE,而第7、8行为在名为“ threeconswins”的新列中为true,以此类推。 最好的方法是什么?

>         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

我假设第1行应为标头,因此实际上,第2行,第5行,第6行和第7行对于“ twoconswins”应评估为TRUE,而第6行和第7行对于“ threeconswins”应评估为TRUE。

您可以这样做:

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场胜利,并且您也希望为此创建专栏。

如果您还希望自动创建新的列,以防万一有时发生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

顺便说一句,我只添加了最后一行,因为(FALSE&TRUE&TRUE&NA)== TRUE的值为FALSE,而您可能希望这些单元格为NA。 我只是通过在此之后将对称子矩阵的上三边形设置为NA来确保这一点。 为了提高可读性,我在此处手动添加了列号9和12,但是如果需要,您也可以指定带有功能的列。

更新:当按照弗兰克的建议使用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")))
 }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM