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.
