Причина, по которой вы получаете эти выходные данные, в том, что Prices[, names(Prices) != "Date"]
возвращает логический вектор:
> Prices[, names(Prices) != "Date"]
[1] FALSE TRUE TRUE TRUE
И поскольку вы можете выполнять вычисления с помощью логики, вы также можете использовать diff
для логического вектора.FALSE
затем обрабатывается как 0
, а TRUE
как 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")]