Let's suppose I have the following data.frame df
:
set.seed(1)
df = data.frame(a = rnorm(10),
b = rnorm(10),
c = rnorm(10),
d = rnorm(10))
> df
a b c d
1 -0.6264538 1.51178117 0.91897737 1.35867955
2 0.1836433 0.38984324 0.78213630 -0.10278773
3 -0.8356286 -0.62124058 0.07456498 0.38767161
4 1.5952808 -2.21469989 -1.98935170 -0.05380504
5 0.3295078 1.12493092 0.61982575 -1.37705956
6 -0.8204684 -0.04493361 -0.05612874 -0.41499456
7 0.4874291 -0.01619026 -0.15579551 -0.39428995
8 0.7383247 0.94383621 -1.47075238 -0.05931340
9 0.5757814 0.82122120 -0.47815006 1.10002537
10 -0.3053884 0.59390132 0.41794156 0.76317575
I desire to shift up (only) columns b
, c
and d
by let's say 3 rows. Column a
has to remain fixed and the rows with NAs
removed.
Here my desired output for a shift of 3 rows:
> df_shift_3
a b c d
1 -0.6264538 -2.21469989 -1.98935170 -0.05380504
2 0.1836433 1.12493092 0.61982575 -1.37705956
3 -0.8356286 -0.04493361 -0.05612874 -0.41499456
4 1.5952808 -0.01619026 -0.15579551 -0.39428995
5 0.3295078 0.94383621 -1.47075238 -0.05931340
6 -0.8204684 0.82122120 -0.47815006 1.10002537
7 0.4874291 0.59390132 0.41794156 0.76317575
How can I create a function that generalise this output for a up
or down
shift of n
rows?
I tried to use the following function https://rdrr.io/cran/useful/man/shift.column.html but no success.
Thanks for any help
The lead/lag
function from dplyr are helpful for this. df %>% mutate_at(-1, ~lead(., 3)) %>% slice(1:(n()-3))
And you can make it a function
shift_all_but_first <- function(data, N) data %>% mutate_at(-1, ~lead(., N)) %>% slice(1:(n()-N))
shift_all_but_first(df, 3)