Мы могли бы легко сделать это, используя dplyr
, сначала расположив даты, а затем разделив values
на first
value
на группы (ID
).
library(dplyr)
dat %>%
arrange(dates) %>%
group_by(ID) %>%
mutate(ratio = values/first(values))
ИЛИ
dat %>%
arrange(dates) %>%
group_by(ID) %>%
mutate(ratio = values/values[1L])
# values ID dates ratio
# <dbl> <fct> <date> <dbl>
# 1 24.0 A 2019-01-01 1
# 2 32.1 B 2019-01-01 1
# 3 27.2 C 2019-01-01 1
# 4 31.4 B 2019-01-02 0.976
# 5 32.5 C 2019-01-02 1.20
# 6 25.5 A 2019-01-02 1.07
# 7 35.4 C 2019-01-03 1.30
# 8 27.1 A 2019-01-03 1.13
# 9 27.6 B 2019-01-03 0.859
#10 18.3 A 2019-01-04 0.762
#11 27.3 B 2019-01-04 0.848
#12 25.0 C 2019-01-04 0.920
Базовый подход R с использованием ave
, здесь мы получаем минимальный индекс строки для каждого ID
и затем делим соответствующий values
на values
в группе.
dat$ratio <- with(dat, values/values[ave(order(dates), ID, FUN = min)])
dat
# values ID dates ratio
#1 23.96467 A 2019-01-01 1.0000000
#2 31.38715 B 2019-01-02 0.9764050
#3 35.42221 C 2019-01-03 1.3033536
#4 18.27151 A 2019-01-04 0.7624353
#5 32.14562 B 2019-01-01 1.0000000
#6 32.53028 C 2019-01-02 1.1969457
#7 27.12630 A 2019-01-03 1.1319287
#8 27.26684 B 2019-01-04 0.8482287
#9 27.17774 C 2019-01-01 1.0000000
#10 25.54981 A 2019-01-02 1.0661449
#11 27.61404 B 2019-01-03 0.8590294
#12 25.00807 C 2019-01-04 0.9201673
data
set.seed(1234)
values <- rnorm(12, 30, 5)
ID <- rep(c('A', 'B', 'C'), 4)
dates <- rep(as.Date(c("2019-01-01", "2019-01-02", "2019-01-03", "2019-01- 04")), 3)
dat <- data.frame(values, ID, dates)