R how can I calculate difference between rows in a data frame

前端 未结 6 2078
挽巷
挽巷 2020-12-03 01:13

Here is a simple example of my problem:

> df <- data.frame(ID=1:10,Score=4*10:1)
> df
       ID Score
    1   1    40
    2   2    36
    3   3    3         


        
6条回答
  •  不知归路
    2020-12-03 01:44

    I would like to show an alternative way for doing such kind of things even often I have the feeling it is not appreciated doing this in that way: using sql.

    sqldf(paste("SELECT a.ID,a.Score"
                ,"      , a.Score - (SELECT b.Score"
                ,"                   FROM df b"
                ,"                   WHERE b.ID < a.ID"
                ,"                   ORDER BY b.ID DESC"
                ,"                   ) diff"
                ," FROM df a"
                )
          )
    

    The code seems complicated but it is not and it has some advantage, as you can see at the results:

        ID Score diff
     1   1    40 
     2   2    36 -4.0
     3   3    32 -4.0
     4   4    28 -4.0
     5   5    24 -4.0
     6   6    20 -4.0
     7   7    16 -4.0
     8   8    12 -4.0
     9   9     8 -4.0
     10 10     4 -4.0
    

    One advantage is that you use the original dataframe (without converting into other classes) and you get a data frame (put it in res <- ....). Another advantage is that you have still all rows. And the third advantage is that you can easily consider grouping factors. For example:

    df2 <- data.frame(ID=1:10,grp=rep(c("v","w"), each=5),Score=4*10:1)
    
    sqldf(paste("SELECT a.ID,a.grp,a.Score"
                ,"      , a.Score - (SELECT b.Score"
                ,"                   FROM df2 b"
                ,"                   WHERE b.ID < a.ID"
                ,"                         AND a.grp = b.grp"
                ,"                   ORDER BY b.ID DESC"
                ,"                   ) diff"
         ," FROM df2 a"
         )
    )
    
    
       ID grp Score diff
    1   1   v    40 
    2   2   v    36 -4.0
    3   3   v    32 -4.0
    4   4   v    28 -4.0
    5   5   v    24 -4.0
    6   6   w    20 
    7   7   w    16 -4.0
    8   8   w    12 -4.0
    9   9   w     8 -4.0
    10 10   w     4 -4.0
    

提交回复
热议问题