Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get difference between rows for all columns in R

Tags:

for-loop

r

dplyr

This is the input:

 book1 <- structure(
      list(
        ID = 1:10, 
        X1 = c(123L, 434L, 545L, 2323L, 54L,
               23L, 54L, 24L, 53L, 44L),
        X2 = c(132L, 44L, 543L, 335L, 53L,
               33L, 42L, 24L, 35L, 55L),
        X3 = c(12L, 143L, 533L, 344L, 232L,
               5332L, 23L, 333L, 56L, 75L),
        X4 = c(123L, 434L, 545L, 2323L,
               54L, 23L, 54L, 24L, 53L, 44L),
        X5 = c(132L, 44L, 543L, 335L,
               53L, 33L, 42L, 24L, 35L, 55L),
        X6 = c(12L, 143L, 533L, 344L,
               232L, 5332L, 23L, 333L, 56L, 75L),
        X7 = c(123L, 434L, 545L, 2323L,
               54L, 23L, 54L, 24L, 53L, 44L),
        X8 = c(132L, 44L, 543L, 335L,
               53L, 33L, 42L, 24L, 35L, 55L),
        X9 = c(12L, 143L, 533L, 344L,
               232L, 5332L, 23L, 333L, 56L, 75L),
        X10 = c(123L, 434L, 545L,
                2323L, 54L, 23L, 54L, 24L, 53L, 44L),
        X11 = c(132L, 44L, 543L,
                335L, 53L, 33L, 42L, 24L, 35L, 55L),
        X12 = c(12L, 143L, 533L,
                344L, 232L, 5332L, 23L, 333L, 56L, 75L)
      ),
      class = "data.frame",
      row.names = c(NA,-10L)
    )

And this is the input I'm expecting: expected result

I think I should use for loop and the lag function, but can't get it to work. I want the first stays the same, and get the difference starting the second row.

like image 898
Solicia Avatar asked Sep 12 '25 07:09

Solicia


1 Answers

We may use diff with rbind - diff get the column wise difference between adjacent elements with length 1 less than the original number of rows and rbind the first row

rbind(book1[1,], diff(as.matrix(book1)))

-output

      X1   X2    X3    X4   X5    X6    X7   X8    X9   X10  X11   X12
1    123  132    12   123  132    12   123  132    12   123  132    12
2    311  -88   131   311  -88   131   311  -88   131   311  -88   131
3    111  499   390   111  499   390   111  499   390   111  499   390
4   1778 -208  -189  1778 -208  -189  1778 -208  -189  1778 -208  -189
5  -2269 -282  -112 -2269 -282  -112 -2269 -282  -112 -2269 -282  -112
6    -31  -20  5100   -31  -20  5100   -31  -20  5100   -31  -20  5100
7     31    9 -5309    31    9 -5309    31    9 -5309    31    9 -5309
8    -30  -18   310   -30  -18   310   -30  -18   310   -30  -18   310
9     29   11  -277    29   11  -277    29   11  -277    29   11  -277
10    -9   20    19    -9   20    19    -9   20    19    -9   20    19

Or an option in tidyverse

library(dplyr)
book1 %>%
  mutate(across(everything(),  ~ coalesce(.x -lag(.x), .x)))
like image 176
akrun Avatar answered Sep 13 '25 23:09

akrun