R: Differences by group and adding

后端 未结 3 413
Happy的楠姐
Happy的楠姐 2020-12-22 03:56

I would like to know how to do this operation simpler.
Imagine I have a data.frame like this one:

set.seed(1)
ID <- rep(1:3,each=4)
XX <- round(run         


        
相关标签:
3条回答
  • 2020-12-22 04:38

    I think you will need to use lapply() across the relevant columns, as ave() will not take a list in its first argument. Try this:

    df[-1] <- lapply(
        df[-1], 
        function(x) ave(x, df$ID, FUN = function(x) c(x[1], diff(x)))
    )
    

    which gives the updated df

       ID     XX    ZZ
    1   1  0.266 0.266
    2   1  0.106 0.744
    3   1  0.201 1.719
    4   1  0.335 3.632
    5   2  0.202 0.202
    6   2  0.696 1.796
    7   2  0.047 2.835
    8   2 -0.284 2.644
    9   3  0.629 0.629
    10  3 -0.567 0.124
    11  3  0.144 0.618
    12  3 -0.029 0.708
    

    Data:

    df <- structure(list(ID = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L, 
    3L, 3L), XX = c(0.266, 0.372, 0.573, 0.908, 0.202, 0.898, 0.945, 
    0.661, 0.629, 0.062, 0.206, 0.177), ZZ = c(0.266, 1.01, 2.729, 
    6.361, 0.202, 1.998, 4.833, 7.477, 0.629, 0.753, 1.371, 2.079
    )), .Names = c("ID", "XX", "ZZ"), class = "data.frame", row.names = c(NA, 
    -12L))
    
    0 讨论(0)
  • 2020-12-22 04:54

    Here is a simple way to do it in a data.table

    set.seed(1)
    ID <- rep(1:3, each=4)
    XX <- round(runif(12), 3)
    ##ZZ <- ave(XX*TT,ID, FUN = cumsum) #we don't have TT
    DF <- data.table(ID, XX)
    
    DF[,XX_dif:=XX-c(0,head(XX,length(XX)-1)),by=ID]
    # or alternatively using shift()
    # DF[, XX_dif := XX-shift(XX, fill=0L), by=ID]
    
        ID    XX XX_dif
     1:  1 0.266  0.266
     2:  1 0.372  0.106
     3:  1 0.573  0.201
     4:  1 0.908  0.335
     5:  2 0.202  0.202
     6:  2 0.898  0.696
     7:  2 0.945  0.047
     8:  2 0.661 -0.284
     9:  3 0.629  0.629
    10:  3 0.062 -0.567
    11:  3 0.206  0.144
    12:  3 0.177 -0.029
    
    0 讨论(0)
  • 2020-12-22 04:54

    Here is an option using dplyr

    library(dplyr)
    DF %>% 
       group_by(ID) %>%
       mutate(ZZ = c(ZZ[1], diff(ZZ)))
    #      ID    XX    ZZ
    #    <int> <dbl> <dbl>
    #1      1 0.266 0.266
    #2      1 0.372 0.744
    #3      1 0.573 1.719
    #4      1 0.908 3.632
    #5      2 0.202 0.202
    #6      2 0.898 1.796
    #7      2 0.945 2.835
    #8      2 0.661 2.644
    #9      3 0.629 0.629
    #10     3 0.062 0.124
    #11     3 0.206 0.618
    #12     3 0.177 0.708
    
    0 讨论(0)
提交回复
热议问题