Home > database >  How to shift data in only one column up and down in R?
How to shift data in only one column up and down in R?

Time:02-05

I have a data frame that looks as follows:

ID Count
1 3
2 5
3 2
4 0
5 1

And I am trying to shift ONLY the values in the "Count" column down one so that it looks as follows:

ID Count
1 NA
2 3
3 5
4 2
5 0

I will also need to eventually shift the same data up one:

ID Count
1 5
2 2
3 0
4 1
5 NA

I've tried the following code:

shift <- function(x, n){
        c(x[-(seq(n))], rep(NA, n))
        }
      
      df$Count <- shift(df$Count, 1)

But it ended up duplicating the titles and shifting the data down, like as follows:

ID Count
ID Count
1 3
2 5
3 2
4 0

Is there an easy way for me to accomplish this? Thank you!!

CodePudding user response:

# set as data.table
setDT(df)

# shift
df[, count := shift(count, 1)]

CodePudding user response:

First use dplyr::lag() to shift your whole dataframe down by 1 row, then use fill(ID, .direction = "up) to fill the NA in the ID column.

library(dplyr)
library(tidy)

lag(df) %>% fill(ID, .direction = "up")

# A tibble: 5 x 2
     ID Count
  <int> <int>
1     1    NA
2     1     3
3     1     5
4     1     2
5     1     0

CodePudding user response:

df$Count=c(NA, df$Count[1:(nrow(df)-1)])

CodePudding user response:

1) dplyr Using DF shown reproducibly in the Note at the end, use lag and lead from dplyr

library(dplyr)

DF %>% mutate(CountLag = lag(Count), CountLead = lead(Count))
##   ID Count CountLag CountLead
## 1  1     3       NA         5
## 2  2     5        3         2
## 3  3     2        5         0
## 4  4     0        2         1
## 5  5     1        0        NA

2) zoo This creates a zoo object using zoo's vectorized lag. Optionally use fortify.zoo(z) or as.ts(z) to convert it back to a data frame or ts object.

Note that dplyr clobbers lag with its own lag so we used stats::lag to ensure it does not interfere. The stats:: can optionally be omitted if dplyr is not loaded.

library(zoo)

z <- stats::lag(read.zoo(DF), seq(-1, 1)); z
  Index lag-1 lag0 lag1
1     1    NA    3    5
2     2     3    5    2
3     3     5    2    0
4     4     2    0    1
5     5     0    1   NA

3) collapse flag from the collapse package is also vectorized over its second argument.

library(collapse)

with(DF, data.frame(ID, Count = flag(Count, seq(-1, 1))))
##   ID Count.F1 Count... Count.L1
## 1  1        5        3       NA
## 2  2        2        5        3
## 3  3        0        2        5
## 4  4        1        0        2
## 5  5       NA        1        0

Note

DF <- data.frame(ID = 1:5, Count = c(3, 5, 2, 0, 1))

CodePudding user response:

Check out this library called DataEditR. I believe you can manually shift data using this library.

  •  Tags:  
  • Related