Как сложить функцию по определенному диапазону в R?

Вот три столбца:

indx    vehID   LocalY
1   2   35.381
2   2   39.381
3   2   43.381
4   2   47.38
5   2   51.381
6   2   55.381
7   2   59.381
8   2   63.379
9   2   67.383
10  2   71.398
11  2   75.401
12  2   79.349
13  2   83.233
14  2   87.043
15  2   90.829
16  2   94.683
17  2   98.611
18  2   102.56
19  2   106.385
20  2   110.079
21  2   113.628
22  2   117.118
23  2   120.6
24  2   124.096
25  2   127.597
26  2   131.099
27  2   134.595
28  2   138.081
29  2   141.578
30  2   145.131
31  2   148.784
32  2   152.559
33  2   156.449
34  2   160.379
35  2   164.277
36  2   168.15
37  2   172.044
38  2   176
39  2   179.959
40  2   183.862
41  2   187.716
42  2   191.561
43  2   195.455
44  2   199.414
45  2   203.417
46  2   207.43
47  2   211.431
48  2   215.428
49  2   219.427
50  2   223.462
51  2   227.422
52  2   231.231
53  2   235.001
54  2   238.909
55  2   242.958
56  2   247.137
57  2   251.247
58  2   255.292
59  2   259.31
60  2   263.372
61  2   267.54
62  2   271.842
63  2   276.256
64  2   280.724
65  2   285.172

Я хочу создать новый столбец под названием «Сглаженный Y», применяя следующую формулу:

D = 15, дельта (треугольный символ) = 5, i = indx, x_alpha (tk) = LocalY, x_alpha (ti) = сглаженное значение

Я попытался использовать следующий код для первого вычисления Z: (Ядро ниже означает функцию exp)

t <- 0.5
dt <- 0.1
delta <- t/dt
d <- 3*delta
indx <- a$indx
for (i in indx) {
initial <- i-d
end <- i+d
k <- c(initial:end)
for (n in k) {
kernel <- exp(-abs(i-n)/delta)
z <- sum(kernel)
}
}
a$z <- z
print (a)

ПРИМЕЧАНИЕ. «A» - импортированный фрейм данных, содержащий три столбца выше.

Хотя значения вычисляемой функции хороши, но она не суммирует значения в переменной z. Как я могу сделать суммирование в диапазоне от i-d до i + d для каждого значения indx i?

 Frank08 окт. 2013 г., 02:31
Держа D и i постоянными, Z и X являются векторами в диапазоне от k ... где для Z я имею в виду ваш экспоненциальный член.
 Frank08 окт. 2013 г., 02:29
z=z+kernel может сработать, если вы действительно хотите зациклить. Но, учитывая структуру проблемы, имеет смысл сделать два упомянутых вектора DWin. Ваше конечное значение простоZ'X/sum(Z)
 42-08 окт. 2013 г., 02:27
Не могли бы вы написать функцию, которая возвращает значение для Z (i, D), и другую функцию, которая использовала его для возврата локальной суммы sum_i Затем вычислите эту сумму в диапазоне «i», где у вас будет достаточно данных для формирования суммы.
 umair durrani08 окт. 2013 г., 02:31
@DWin Я не понял твоего предложения. Вы можете видеть, что функция Z содержит члены i и k, для которых требуется сумма
 Frank08 окт. 2013 г., 02:25
Вы перезаписываете "z" и "kernel" внутри цикла "n". Пытатьсяz = z + kernel.

Ответы на вопрос(1)

Решение Вопроса

Вы можете использоватьconvolve функция. Вам нужно решить, что делать с индексами ближе к любому концу массива, чем к ширине ядра свертки. Один из вариантов - просто использовать частичное ядро, масштабированное таким образом, чтобы веса по-прежнему составляли 1.

smooth<-function(x,D,delta){
  z<-exp(-abs(-D:D)/delta)
  r<-convolve(x,z,type="open")/convolve(rep(1,length(x)),z,type="open")  
  r<-head(tail(r,-D),-D)
  r
}

С вашим массивом какy, результат такой:

> yy<-smooth(y,15,5)
> yy
 [1]  50.70804  52.10837  54.04788  56.33651  58.87682  61.61121  64.50214
 [8]  67.52265  70.65186  73.87197  77.16683  80.52193  83.92574  87.36969
[15]  90.84850  94.35809  98.15750 101.93317 105.67833 109.38989 113.06889
[22] 116.72139 120.35510 123.97707 127.59293 131.20786 134.82720 138.45720
[29] 142.10507 145.77820 149.48224 153.21934 156.98794 160.78322 164.60057
[36] 168.43699 172.29076 176.15989 180.04104 183.93127 187.83046 191.74004
[43] 195.66223 199.59781 203.54565 207.50342 211.46888 215.44064 219.41764
[50] 223.39908 227.05822 230.66813 234.22890 237.74176 241.20236 244.60039
[57] 247.91917 251.14346 254.25876 257.24891 260.09121 262.74910 265.16057
[64] 267.21598 268.70276

Конечно, проблема в том, что ядро оказывается нецентрированным по краям. Это хорошо известная проблема, и есть способы ее решения, но она усложняет проблему. График данных покажет вам эффекты этого нецентрирования:

plot(y)
lines(yy) 

 cryo11108 окт. 2013 г., 03:10
filter также может быть использован. @mrip Кстати: переход к относительным координатам\tau=k-i это видноZ постоянная Таким образом, вы можете нормализовать свой (строчные)z вместо использования второгоconvolve.
 cryo11108 окт. 2013 г., 03:30
Хорошо! Я понимаю. Очень хороший ответ, кстати.
 umair durrani08 окт. 2013 г., 03:34
Мне очень жаль, что я немного не понял из вашего решения. Не могли бы вы привести меня к любой документации R, где я мог бы понять функцию свертки?
 mrip08 окт. 2013 г., 03:24
@ cryo111 Причина, по которой я использовал второе свертывание, состоит в том, чтобы просто правильно нормализовать ядро по краям, где часть ядра выходит за пределы конца массива. Если бы не края, мы могли бы просто нормализоватьz один раз. Я также мог бы нормализоватьz только один раз, а затем написал еще немного кода, чтобы справиться с переоценкой по краям, но я был ленив, и поэтому я сделал это менее эффективным способом.
 mrip08 окт. 2013 г., 03:35
Печатать?convolve (или же?filter) в приглашении R.

Ваш ответ на вопрос