Эту проблему лучше всего показать на примере, и она немного отличается от заданного здесь вопроса: Применение функции к последовательным подвекторам одинакового размера
Допустим, у меня есть некоторые данные о ценах для компаний «МММ» и «АВТ», например (даты цен хранятся в именах строк этого фрейма данных):
> a
MMM ABT
1991-01-02 11.01 2.58
1991-01-03 10.83 2.48
1991-01-04 10.80 2.43
1991-01-07 10.67 2.39
1991-01-08 10.39 2.42
1991-01-09 10.18 2.42
1991-01-10 10.33 2.43
1991-01-11 10.59 2.44
1991-01-14 10.60 2.38
1991-01-15 10.54 2.39
Во-первых, вероятно, необходимо разбить даты в этом кадре данных на равные интервалы «j». Допустим, j = 2. Вот интервалы, на которые мы будем смотреть:
interval1 is from 1991-01-02 to 1991-01-03
interval2 is from 1991-01-04 to 1991-01-07
interval3 is from 1991-01-08 to 1991-01-09
interval4 is from 1991-01-10 to 1991-01-11
interval5 is from 1991-01-14 to 1991-01-15
Я хочу включить последнее значение, если его там нет, поэтому я использую unique() ниже. Таким образом, предполагая длину интервала «j», мы могли бы использовать их как-то (может быть лучший способ сгенерировать вышеуказанные интервалы):
beg <- rownames(a)[seq(1,nrow(a),2)]
# case for j = 2:
# [1] "1991-01-02" "1991-01-04" "1991-01-08" "1991-01-10" "1991-01-14"
end <- rownames(a)[seq(1,nrow(a),2)+1]
end <- unique(c(end[!is.na(end)],rownames(a)[nrow(a)]))
# case for j = 2:
# [1] "1991-01-03" "1991-01-07" "1991-01-09" "1991-01-11" "1991-01-15"
Отсюда у меня есть другой фрейм данных (b), который имеет такие данные:
> b
portfolio_return
1991-01-09 0.010524144
1991-01-10 -0.010706638
1991-01-11 -0.015665796
1991-01-14 -0.015151515
1991-01-15 0.055000000
1991-01-16 -0.052173913
1991-01-21 -0.010204082
То, что я хочу сделать, это найти среднее значение в течение каждого из этих интервалов. Например:
interval1_values = "NA"
interval2_values = "NA"
interval3_values = c(0.010524144)
interval4_values = c(-0.010706638,-0.015665796)
interval5_values = c(-0.015151515, 0.055000000)
#From this we can then easily calculate the average over each interval.
average1 = mean(interval1_values)
average2 = mean(interval2_values)
#etc...
Мое текущее решение выглядит примерно так:
averages_interval <- function(a,b,j){
# replace 2 with j
beg <- rownames(a)[seq(1,nrow(a),j)]
# replace 2 with j
# replace 1 with j-1
end <- rownames(a)[seq(1,nrow(a),j)+j-1]
end <- unique(c(end[!is.na(end)],rownames(a)[nrow(a)]))
c <- rownames(b)
tmp <- c()
j <- 1
# these loops match our c-vector values in their proper interval
# for j = 2 case, it places c[1] in interval3, c[2] in interval4, and so on...
for(i in 1:length(c)){
while(j <= length(end)){
if(c[i]>=beg[j] && c[i]<=end[j]){
tmp <- c(tmp,j)
}
j <- j+1
}
j <- tmp[length(tmp)]
}
df <- data.frame(b,group=tmp)
df <- df[complete.cases(df),]
#row_names <- rownames(df)
# variable needed to store dates if needed later on since we use data.table
df <- data.table(df)
averages <- df[,list(mean=mean(portfolio_return)),by=group][[2]]
return(averages)
}
###### for j = 2
group mean
1: 2 0.01052414
2: 3 0.01318622
3: 4 0.01992424
Есть ли более эффективный метод решения этой проблемы?
Спасибо большое.