r - 取数据子集在 data.table 中进行计算
问题描述
假设我有这个data.table:
df = data.table(date = c(20180101, 20180102, 20180103, 20180104, 20180105, 20180106, 20180107, 20180108, 20180109, 20180110, 20180111, 20180112, 20180113, 20180114, 20180115, 20180116, 20180117, 20180118), value = c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18))
我想做一些使用数据子集的计算(例如平均值)。例如:在 20180103 中,平均值将是(昨天)20180102 和(今天)20180103 值的总和((2+3)/2 = 2.5)。然后滚动到周期结束。
结果是这样的:
date mean
20180102 1.5
20180103 2.5
20180104 3.5
20180105 4.5
....
显然我可以编写一个 for 循环,为每次迭代对数据进行子集化,然后计算平均值,存储数据并输出结果。使用for循环被认为太慢了,使用foreach我不知道如何保存结果......
for 循环是这样的:
datelist = df[, .(date)]
# initialize the object
data = NA
temp = 0
for (i in 2:nrow(datelist)) {
today = as.numeric(datelist[i])
yesterday = as.numeric(datelist[i-1])
temp = df[date >= yesterday & date <= today]
temp = temp[, .(mean(value))]
temp = cbind(datelist[i], mean = temp$V1)
if (is.na(data)[1]){
data=temp
} else {
data=rbind(data,temp)
}
}
您可以看到我首先对数据进行子集化并将其称为 temp 然后进行计算(平均,使用它来执行 lm,然后将其堆叠到数据对象中的任何函数)
这是缓慢且低效的,因为我有数百万个数据点
无论如何我可以在 data.table 语法中做到这一点:
result = df[, { data = .SD[date >= yesterday & date <= today]
mean = mean(data$value)
list(mean = mean)}, by=.(date)]
不知道怎么表达昨天和今天??因此,在 for 循环的情况下,昨天是 i-1,而今天是 i?
我在 by=.(date) 时的理解是 data.table 将查看每个日期并计算您提供的任何函数。如果我能得到 data.table 现在正在查看的日期的值(即 i) ,那么值 (i-1) 将是昨天...
谢谢
解决方案
您可以在子句中使用shift
运算符:data.table
j
df[order(date),
rollmean := (value + shift(value, n = 1, type = "lag"))/2][]
date value rollmean
1: 20180101 1 NA
2: 20180102 2 1.5
3: 20180103 3 2.5
4: 20180104 4 3.5
5: 20180105 5 4.5
6: 20180106 6 5.5
7: 20180107 7 6.5
8: 20180108 8 7.5
...
推荐阅读
- python - Python - 在循环中针对不同变量运行相同的代码块
- sql-server - SQL Server 外键数据问题
- amazon-web-services - 每次调用函数时,AWS Lambda 是否都会加载模型?
- mongodb - PyMongo 转换日期字段
- c++ - 如何在 C++20 中使用 std::indirect_result_t
- php - 使用php在mongodb的数组中插入数组
- javascript - 如何延迟 JS 函数运行直到页面加载后 5 秒
- vue.js - i18n 形式的翻译
- python - 是否可以在不硬编码列表位置的情况下识别 json 字典列表中的项目?
- gmail - 是否可以通过 GMAIL RESTful API 发送电子邮件而无需在已发送文件夹中保存副本?