using tidyverse; counting after and before change in value, within groups, generating new variables for each unique shift

后端 未结 3 730
南旧
南旧 2021-01-04 04:45

I am looking for a tidyverse-solution that can count occurrences of unique values of TF within groups, id in the data datatbl

3条回答
  •  礼貌的吻别
    2021-01-04 05:22

    I had a answer without data.table but it was not using dplyr. Here is my attempt using dplyr:

            #Remove the NAs 
    dfr <-  df %>% filter(!is.na(TF)) %>% 
      # group by id
      group_by(id) %>% 
      # Calculate the rle on TF for each group
      do(., mrle = rle(.$TF)) %>% mutate(Total=sum(mrle$lengths)) %>%
      # Trasform the rle result in a data.frame counting the values after and before changes
      do( {
      t<- .$mrle
      #for each length generate the columns
      res <- as.data.frame(lapply(seq_along(t$lengths[-length(t$lengths)]), function(i) {
    
          #before change counts
          n1 <- t$lengths[i]
          #position  the counts
          if(i==1) {
            before <- 0
          } else {
            before <- sum(t$lengths[1:i-1])
          }
    
          #after change conts
          n2 <- t$lengths[i+1]
    
          if(i == (length(t$lengths)-1))
            after  <- 0
          else
            after <- .$Total - before - n1 - n2
    
          # assemble the column
          c(rep(NA,before),-n1:-1,1:n2, rep(NA,after))
    
        } ))
    
      colnames(res) <- paste0("PM", 1:ncol(res))
      #preserve the id
      cbind(id=.$id,res)
    
     })
    
    #Join with the original data.frame
    res <-  df %>% mutate(rn = row_number()) %>% filter(!is.na(TF)) %>% bind_cols(dfr) %>% right_join( df %>% mutate(rn = row_number()) ) %>% select(-rn, -id1)
    
    #Verify
    mapply(all.equal, dfa,res)
    #  id   TF PM01 PM02 PM03 PM04 PM05 
    #TRUE TRUE TRUE TRUE TRUE TRUE TRUE
    

提交回复
热议问题