Reputation: 387
Using example data like this:
example=data.frame(x=c(1,2,3,4,5,6,7,8), y=c(1,2,3,4,5,6,7,8), z=c(1,2,3,4,5,6,7,8))
which looks like this:
x y z
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
5 5 5 5
6 6 6 6
7 7 7 7
8 8 8 8
I would like to shift all values in the z column upwards by two rows while the rest of the dataframe remains unchanged. The result should look like this:
x y z
1 1 1 3
2 2 2 4
3 3 3 5
4 4 4 6
5 5 5 7
6 6 6 8
7 7 7 NA
8 8 8 NA
I only found ways to move the values of a column down, or a shifting of the whole dataframe.
Any ideas? Thanks!
Upvotes: 18
Views: 36313
Reputation: 1
## In case you want to shift your rows down by one step for only one column
`z <- example$'z'`
# Deleting the last z value in order to shift values
# ahead by one period to realign with other rows
z_1 <-head(z,-1)
# We set the initial z value to zero
for (i in 1: (length(z)+1)) {
if(i != 1){
z[i] = Z_1[i-1]}
else{
z[i] = 0
}
}
Z
# Append Z to dataframe
example$z <- z
Upvotes: 0
Reputation: 51
This function in the 'useful' package moves columns in both direction: https://www.rdocumentation.org/packages/useful/versions/1.2.6/topics/shift.column
Upvotes: -2
Reputation: 3321
example = tibble(x=c(1,2,3,4,5,6,7,8),
y=c(1,2,3,4,5,6,7,8),
z=c(1,2,3,4,5,6,7,8))
example %>% mutate_at(c("z"), funs(lead), n = 2 )
# A tibble: 8 x 3
x y z
<dbl> <dbl> <dbl>
1 1.00 1.00 3.00
2 2.00 2.00 4.00
3 3.00 3.00 5.00
4 4.00 4.00 6.00
5 5.00 5.00 7.00
6 6.00 6.00 8.00
7 7.00 7.00 NA
8 8.00 8.00 NA
Upvotes: 10
Reputation: 92292
I couldn't find a good duplicate, so here's another solution using length<-
shift2 <- function(x, n) `length<-`(tail(x, -n), length(x))
# or just shift2 <- function(x, n) c(tail(x, -n), rep(NA, n))
transform(example, z = shift2(z, 2))
# x y z
# 1 1 1 3
# 2 2 2 4
# 3 3 3 5
# 4 4 4 6
# 5 5 5 7
# 6 6 6 8
# 7 7 7 NA
# 8 8 8 NA
Upvotes: 2
Reputation: 179428
Your problem simplifies to:
n
elements in a vectorn
values of NA
at the endYou can do this with a simple function:
shift <- function(x, n){
c(x[-(seq(n))], rep(NA, n))
}
example$z <- shift(example$z, 2)
The result:
example
x y z
1 1 1 3
2 2 2 4
3 3 3 5
4 4 4 6
5 5 5 7
6 6 6 8
7 7 7 NA
8 8 8 NA
Upvotes: 20