从同一变量中的多个值计算 R 中的变量

Computing Variables in R from Multiple Values in the Same Variable

假设我们有一个名为 df 的数据集,这个数据集由两个名为 year 和 x1 的变量组成:

year <- c(2000, 2001, 2002, 2003, 2004)
x1 <- c(7, 8, 6, 3, 3)
df <- data.frame(year, x1)

我的任务是根据 x1 计算两个新变量。第一个变量是 cSum,它必须反映过去两年 x1 值的总和。第二个变量是 cMax,它必须反映最近三年中 x1 的最高值。

结果应该是这样的:

year  x1  cSum  cMax
2000   7     
2001   8    15     
2002   6    14     8
2003   3     9     8
2004   3     6     6

如何计算上面的 cSum 和 cMax 变量?

谢谢!

使用data.table:

library(data.table)
setDT(df)

一是曲折;由于 transpose 已优化,此 可能 更快(未经测试):

df[ , cSum := transpose(lapply(transpose(shift(x1, 0:1)), sum))]
df[ , cMax := transpose(lapply(transpose(shift(x1, 0:2)), max))]

shift 本质上是一个滞后运算符;我们需要滞后 0、1 和(对于 cMax)2 来获取当前和之前的 1(或 2)个周期。

或者:

df[ , cSum := rowSums(do.call(cbind, shift(x1, 0:1)))]
df[ , cMax := do.call(pmax, shift(x1, 0:2))]

两者给出相同的输出:

df
#    year x1 cSum cMax
# 1: 2000  7   NA   NA
# 2: 2001  8   15   NA
# 3: 2002  6   14    8
# 4: 2003  3    9    8
# 5: 2004  3    6    6

让事情变得混乱的是,当 shift returns 超过一个延迟时,它 returns a list;但不幸的是,这个列表是我们需要的转置(我们正在进行按行操作,并且它是以列友好的方式生成的)。第一个选项 transpose 以更易于管理的形式获取列表,然后在 transpose 返回列形式之前进行行操作。

第二个选项将输出转换为数组并对数组进行逐行操作。

这是一种利用滞后算子的方法。本质上,我正在扩充您的数据,以尽量减少对循环的需求。这样做,我增加了使用的内存量。如果您要使用此数据集进行更多时间序列分析,则此方法可能有意义。在答案中,我使用了 zoo 包,这是我最喜欢的时间序列包。但是,还有很多其他的tsxts(一般比zoo快),...

library(zoo)

year <- c(2000, 2001, 2002, 2003, 2004, 2005)
x1 <- c(7, 8, 6, 3, 3, 6)
df <- data.frame(year, x1)

dfZ <- zoo(df[,-1], order.by = df[,1]) 

dfZ <- merge(dfZ, lag(dfZ, seq(-1, -2)))

names(dfZ) <- paste0("L", seq(0,2))

dfZ$cSum <- rowSums(dfZ[, c("L0", "L1")])
dfZ$cMax <- apply(dfZ[, c("L0", "L1", "L2")], 1, max)