我正在用 R 做一个项目,我有点卡住了。我有四个这种格式的时间序列:
x <- data.frame(Id = rep(c(1,2,3,4),2),
Date = c(rep("1980-01-01",4), rep("1980-01-02",4)),
Freq = c(2,3,1,2,4,5,2,3))
ID Date Freq
1 1980 - 01 - 01 2
2 1980 - 01 - 01 3
3 1980 - 01 - 01 1
4 1980 - 01 - 01 2
1 1980 - 01 - 02 4
2 1980 - 01 - 02 5
3 1980 - 01 - 02 2
4 1980 - 01 - 02 3
我的目标是创建一个新变量,它只是该组昨天的频率值。
ID Date Freq YestFreq
1 1980 - 01 - 01 2 NA
2 1980 - 01 - 01 3 NA
3 1980 - 01 - 01 1 NA
4 1980 - 01 - 01 2 NA
1 1980 - 01 - 02 4 2
2 1980 - 01 - 02 5 3
3 1980 - 01 - 02 2 1
4 1980 - 01 - 02 3 2
我尝试的解决方案是:
x$DateID = paste(x$ID, x$Date)
x$yesterday = as.Date(x$Date) - 1
x$YesterdayDateID = paste(x$ID, x$yesterday)
result = numeric(nrow(x))
for(i in 1:nrow(x)){
answer = x$Freq[which(x$DateID == x$yesterdayDateID[i])]
if(length(answer) != 0){result[i] = answer} else{result[i] = NA}
}
x = cbind(x, result)
我的实际数据集有约 600000 行(约 300 个 ID 和约 2000 个唯一日期),因此我的上述解决方案需要整整 2 小时才能运行。任何帮助将不胜感激。
最佳答案
考虑到昨天可能出现的缺口。我使用 match
来识别前一天。然后从该索引中按 Id 对目标列进行子集化:
数据表
library(data.table)
setDT(x)[, Date := as.IDate(Date)][
, YestFreq := Freq[match(Date-1L, Date)], by=Id][]
# Id Date Freq YestFreq
# 1: 1 1980-01-01 2 NA
# 2: 2 1980-01-01 3 NA
# 3: 3 1980-01-01 1 NA
# 4: 4 1980-01-01 2 NA
# 5: 1 1980-01-02 4 2
# 6: 2 1980-01-02 5 3
# 7: 3 1980-01-02 2 1
# 8: 4 1980-01-02 3 2
dplyr
library(dplyr)
x$Date <- as.Date(x$Date)
x %>% group_by(Id) %>% mutate(YestFreq = Freq[match(Date - 1L, Date)])
# Id Date Freq YestFreq
# 1 1 1980-01-01 2 NA
# 2 2 1980-01-01 3 NA
# 3 3 1980-01-01 1 NA
# 4 4 1980-01-01 2 NA
# 5 1 1980-01-02 4 2
# 6 2 1980-01-02 5 3
# 7 3 1980-01-02 2 1
# 8 4 1980-01-02 3 2
关于r - 为多个时间序列创建“"Yesterday' s Value”变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33678756/