如何标准化为序列中的前一个值

How to normalize to the previous value in a sequence

我正在努力解决的一个概念上简单的问题。我有随着时间的推移按 ID 分组的观察结果 ('Values'),并希望将每个观察结果标准化为之前的观察结果。在下面的示例中,我可以将每个 'Value' 标准化为 ID 组中的第一个 'Time' 观察(即 10 到 10、20 到 10、30 到 10 等),但我想标准化每个 'Value' 到之前的观察结果(即 20 到 10、30 到 20 等),但我无法让它发挥作用。

ID <- c(rep("A", 4), rep("B", 3), rep("C", 3))
Time <- c(10, 20, 30, 40, 10, 20, 30, 10, 20, 30)
Value <- sample(1:100, 10)
dat <- cbind(ID, Time, Value)

newDat <- dat %>%
  arrange(Time) %>%
  group_by(ID) %>%
  mutate(ratio = Value/first(Value))

使用lag获取之前的值。

library(dplyr)

dat %>%
  arrange(ID, Time) %>%
  group_by(ID) %>%
  mutate(ratio = Value/lag(Value))


#   ID     Time Value  ratio
#   <fct> <dbl> <int>  <dbl>
# 1 A        10    53  NA    
# 2 A        20    16  0.302
# 3 A        30    57  3.56 
# 4 A        40    74  1.30 
# 5 B        10    38  NA    
# 6 B        20    54  1.42 
# 7 B        30    61  1.13 
# 8 C        10    78  NA    
# 9 C        20    41  0.526
#10 C        30    83  2.02 

我们也可以使用headtail

dat %>%
  arrange(ID, Time) %>%
  group_by(ID) %>%
  mutate(ratio = c(NA, tail(Value, -1)/head(Value, -1)))

数据

ID <- c(rep("A", 4), rep("B", 3), rep("C", 3))
Time <- c(10, 20, 30, 40, 10, 20, 30, 10, 20, 30)
Value <- sample(1:100, 10)
dat <- data.frame(ID, Time, Value)

我们可以使用data.table方法

library(data.table)
setDT(df1)[order(Time), ratio := Value/shift(Value), ID]