代码之家  ›  专栏  ›  技术社区  ›  Floni

之后的连续值和R中因子的新水平

  •  1
  • Floni  · 技术社区  · 8 年前

    我有以下样品

    id <- c("a","b","a","b","a","a","a","a","b","b","c")
    SOG <- c(4,4,0,0,0,0,0,0,0,0,9)
    data <- data.frame(id,SOG)
    

    我希望在新的列中显示SOG==0时的累积值。 使用以下代码

    tmp <- rle(SOG)                                    #run length encoding: 
    tmp$values <- tmp$values == 0                      #turn values into logicals 
    tmp$values[tmp$values] <- cumsum(tmp$values[tmp$values]) #cumulative sum of TRUE values 
    inverse.rle(tmp)                                   #inverse the run length encoding 
    

    我创建了列“stop”:

    data$Stops <- inverse.rle(tmp)
    

    我可以进去:

    [1] 0 0 1 1 1 1 1 1 1 1 0
    

    但我想换一个

    [1] 0 0 1 2 3 3 3 3 4 4 0 
    

    我的意思是,当因子“id”的级别与前一行不同时,我想跳到下一个“stop”(I+1)。

    2 回复  |  直到 6 年前
        1
  •  4
  •   Thierry    8 年前

    看看这个 dplyr 包裹

    library(dplyr)
    data %>%
      mutate(
        Stops = ifelse(
          SOG > 0,
          0,
          cumsum(SOG == 0 & lag(id) != id)
        )
      )
    
        2
  •  1
  •   akrun    8 年前

    我们可以试试

    library(data.table)
    setDT(data1)[, v1 := if(all(!SOG)) c(TRUE, id[-1]!= id[-.N]) else
         rep(FALSE, .N), .(grp = rleid(SOG))][,cumsum(v1)*(!SOG)]
    #[1] 0 0 1 2 3 3 3 3 4 4 0 0 0 0 5 5 0 6 6 0
    

    使用旧数据

    setDT(data)[, v1 := if(all(!SOG)) c(TRUE, id[-1]!= id[-.N]) 
           else rep(FALSE, .N), .(grp = rleid(SOG))][,cumsum(v1)*(!SOG)]
    #[1] 0 0 1 2 3 3 3 3 4 4 0
    

    数据

    id <- c("a","b","a","b","a","a","a","a","b","b","c","a","a","a","a","a","a","a","a", "a")
    SOG <- c(4,4,0,0,0,0,0,0,0,0,9,1,5,3,0,0,4,0,0,1)
    data1 <- data.frame(id, SOG, stringsAsFactors=FALSE)