r - 如何计算 data.table 中的回报?
问题描述
我是堆栈溢出的新手和 R 初学者。
我想计算一个大数据集的回报,如下所示:
Date C1 C2 C3
31.01.1985 NA 47 NA
28.02.1985 NA 45 NA
29.03.1985 130 56 NA
30.04.1985 140 67 NA
31.05.1985 150 48 93
28.06.1985 160 79 96
31.07.1985 160 56 94
30.08.1985 160 77 93
30.09.1985 160 66 93
31.10.1985 160 44 93
29.11.1985 160 55 93
这是一种data.table
格式,假设它被称为价格,列是公司,值是价格,实际数据集有更多的列和行。我想建立一个新的 DT 来计算每月的回报,我知道你可以用这个diff()
函数来做到这一点。但是如何在没有 for 循环的情况下构建包含这么多列的新数据表?
我想到了:
Returns <- diff(Prices[, names(Prices) != "Date"])
但这出于某种原因只给出了:
[1] 1 0 0
提前致谢。
解决方案
您获得该输出的原因是因为Prices[, names(Prices) != "Date"]
返回一个逻辑向量:
> Prices[, names(Prices) != "Date"]
[1] FALSE TRUE TRUE TRUE
而且因为您可以使用逻辑进行计算,所以您也可以diff
在逻辑向量上使用。FALSE
然后被视为 a0
和TRUE
a 1
。所以基本上你在做diff(c(0,1,1,1))
。
您想要的可能解决方案:
cols <- setdiff(names(Prices),"Date")
# option 1:
Prices[, paste0(cols,"_return") := lapply(.SD, function(x) (x - shift(x, fill = NA))/shift(x, fill = NA)), .SDcols = cols][]
# option 2:
Prices[, paste0(cols,"_return") := lapply(.SD, function(x) c(NA,diff(x))/shift(x, fill = NA)), .SDcols = cols][]
这使:
> Prices Date C1 C2 C3 C1_return C2_return C3_return 1: 1985-01-31 NA 47 NA NA NA NA 2: 1985-02-28 NA 45 NA NA -0.04255319 NA 3: 1985-03-29 130 56 NA NA 0.24444444 NA 4: 1985-04-30 140 67 NA 0.07692308 0.19642857 NA 5: 1985-05-31 150 48 93 0.07142857 -0.28358209 NA 6: 1985-06-28 160 79 96 0.06666667 0.64583333 0.03225806 7: 1985-07-31 160 56 94 0.00000000 -0.29113924 -0.02083333 8: 1985-08-30 160 77 93 0.00000000 0.37500000 -0.01063830 9: 1985-09-30 160 66 93 0.00000000 -0.14285714 0.00000000 10: 1985-10-31 160 44 93 0.00000000 -0.33333333 0.00000000 11: 1985-11-29 160 55 93 0.00000000 0.25000000 0.00000000
如果要创建新的data.table
,可以使用以下两个选项之一:
# option 1:
Returns <- Prices[, c(list(Date = Date), lapply(.SD, function(x) (x - shift(x, fill = NA))/shift(x, fill = NA))), .SDcols = cols]
# option 2:
Returns <- copy(Prices)
Returns[, (cols) := lapply(.SD, function(x) (x - shift(x, fill = NA))/shift(x, fill = NA)), .SDcols = cols]
使用数据:
Prices <- fread("Date C1 C2 C3
31.01.1985 NA 47 NA
28.02.1985 NA 45 NA
29.03.1985 130 56 NA
30.04.1985 140 67 NA
31.05.1985 150 48 93
28.06.1985 160 79 96
31.07.1985 160 56 94
30.08.1985 160 77 93
30.09.1985 160 66 93
31.10.1985 160 44 93
29.11.1985 160 55 93")[, Date := as.Date(Date, "%d.%m.%Y")]
推荐阅读
- api - 从 API Flutter FetchData 并使用 sqflite 保存本地
- json - 如何生成具有重复对象的文档
- php - 根据另一个数组显示一个数组的成员
- python - 如何从文件中删除特定文本?
- android - React Native 找不到本地方法
- c - 我在哪里可以下载 dwmapi.lib?
- python - 无法使用 django 将嵌入式文档插入模型
- android - 使用本地计算机内存中的 Glide 和 Retrofit 显示图像
- node.js - TypeORM 存储库 createQueryBuilder 捕获错误但继续执行
- python - 如何在 Windows 10 上为 python 2.7.3 安装 pip?