Мы можем сделать группу по 'id' и получить diff
из 'value'
library(dplyr)
df1 <- df1 %>%
group_by(id) %>%
mutate(difference = c(0, diff(value)))
df1
# A tibble: 6 x 4
# Groups: id [2]
# date id value difference
# <chr> <int> <int> <dbl>
#1 1/1/2019 1234 10 0
#2 1/2/2019 1234 11 1
#3 1/3/2019 1234 12 1
#4 1/1/2019 9876 9 0
#5 1/2/2019 9876 11 2
#6 1/3/2019 9876 6 -5
Здесь «date» уже arrange
d, если нет, то сделать arrange
после преобразования в Date
класс (при условии, что форматом является день-месяц-год)
library(lubridate)
df1 %>%
arrange(id, dmy(date)) %>%
group_by(id) %>%
mutate(difference = c(0, diff(value)))
Обновление
С новым набором данных, после группировки по 'id', мы можем получить разницу между текущим элементом 'value1' с lag
для 'value2' и получить change
, разделив столбец 'разности' на lag
столбец
df2 %>%
arrange(id, dmy(date)) %>%
group_by(id) %>%
mutate(lagvalue2 = lag(value2, default = first(value1))) %>%
ungroup %>%
mutate(difference = value1 - lagvalue2,
change = difference/lagvalue2) %>%
select(-lagvalue2)
# A tibble: 6 x 6
# date id value1 value2 difference change
# <chr> <int> <int> <int> <int> <dbl>
#1 1/1/2019 1234 10 12 0 0
#2 1/2/2019 1234 11 14 -1 -0.0833
#3 1/3/2019 1234 12 15 -2 -0.143
#4 1/1/2019 9876 9 10 0 0
#5 1/2/2019 9876 11 12 1 0.1
#6 1/3/2019 9876 6 9 -6 -0.5
Или используя data.table
library(data.table)
setDT(df2)[order(dmy(date)), lagvalue2 := shift(value2, fill = first(value1)) , id]
df2[, difference := value1 - lagvalue2][, change := difference/lagvalue2]
В base R
мы можем сделать
df1 <- df1[order(df1$id, as.Date(df1$date, "%d/%m/%Y")),]
df1$difference <- with(df1, ave(value, id, FUN = function(x) c(0, diff(x))))
data
df1 <- structure(list(date = c("1/1/2019", "1/2/2019", "1/3/2019", "1/1/2019",
"1/2/2019", "1/3/2019"), id = c(1234L, 1234L, 1234L, 9876L, 9876L,
9876L), value = c(10L, 11L, 12L, 9L, 11L, 6L)), class = "data.frame",
row.names = c(NA,
-6L))
df2 <- structure(list(date = c("1/1/2019", "1/2/2019", "1/3/2019", "1/1/2019",
"1/2/2019", "1/3/2019"), id = c(1234L, 1234L, 1234L, 9876L, 9876L,
9876L), value1 = c(10L, 11L, 12L, 9L, 11L, 6L), value2 = c(12L,
14L, 15L, 10L, 12L, 9L)), class = "data.frame", row.names = c(NA,
-6L))