I have a dataframe as shown below with n columns.
+---+------------+--------+--------+--------+
|id | date|signal01|signal02|signal03|......signal(n)
+---+------------+--------+--------+--------+
|050|2021-01-14 |1 |3 |1 |
|050|2021-01-15 |null |4 |2 |
|050|2021-02-02 |2 |5 |3 |
|051|2021-01-14 |1 |3 |0 |
|051|2021-01-15 |null |null |null |
|051|2021-02-02 |3 |3 |2 |
|051|2021-02-03 |4 |3 |3 |
|052|2021-03-03 |1 |3 |0 |
|052|2021-03-05 |null |3 |null |
|052|2021-03-06 |null |null |2 |
|052|2021-03-16 |3 |5 |5 |.......value(n)
+-------------------------------------------+
I have to add a signal difference value column to each signal as below, excluding null records and keeping first diff value as 0.
+---+------------+--------+-------------+--------+-------------+--------+-------------+
|id | date|signal01|signal01_diff|signal02|signal02_diff|signal03|signal03_diff|......signal(n)
+---+------------+--------+-------------+--------+-------------+--------+-------------+
|050|2021-01-14 |1 |0 |3 |0 |1 |0 |
|050|2021-01-15 |null |null |4 |1 |2 |1 |
|050|2021-02-02 |2 |1 |5 |1 |3 |1 |
|051|2021-01-14 |1 |0 |3 |0 |0 |0 |
|051|2021-01-15 |null |null |null |null |null |null |
|051|2021-02-02 |3 |2 |3 |0 |2 |2 |
|051|2021-02-03 |4 |1 |3 |0 |3 |1 |
|052|2021-03-03 |1 |0 |3 |0 |0 |0 |
|052|2021-03-05 |null |null |3 |0 |null |null |
|052|2021-03-06 |null |null |null |null |2 |2 |
|052|2021-03-16 |3 |2 |5 |2 |5 |3 |.......value(n)
+-----------------------------------------------------------------------+--------------
I have tried with lag and window function, but not getting expected output because of null values.
val w = org.apache.spark.sql.expressions.Window.orderBy("id")
val dfWithLag = df.withColumn("signal01_lag", lag("signal01", 1, 0).over(w))
Above is code for a single column, I have to execute the same for rest n columns.
Is there any optimal way to achieve this?