说我有一个矢量:
l1
对于不同的整数l2
我想要向量的k个连续元素的总和,即我对k = 1的期望输出是向量本身
Public Sub break_data()
Dim row As Integer: row = 500 'Number of rows to read on a column
Dim wks As Object 'Source Sheet
Set wks = ThisWorkbook.Sheets("Sheet1")
Dim wkr As Object 'Result Sheet
Set wkr = ThisWorkbook.Sheets("Sheet2")
Dim i As Integer: i = 1
Dim j As Integer: j = 1 'Column that you want to split
Dim x As Integer: x = 1
Dim y As Integer: y = 1
Do While (i <= 500)
If (Len(Trim(wks.Cells(i, j).Value)) > 0) Then
wkr.Cells(x, y).Value = wks.Cells(i, j).Value
x = x + 1
ElseIf (Len(Trim(wks.Cells(i, j).Value)) = 0) And (x <> 1) Then
x = 1
y = y + 1
End If
i = i + 1
Loop
End Sub
并且对于k = 2:
vec = 1:10
vec
[1] 1 2 3 4 5 6 7 8 9 10
依此类推 - 在这个例子中,k = 10是我想要的最后一个:
k
即。我向量的所有10个条目的总和。
在我的实际数据[1] 1 2 3 4 5 6 7 8 9 10
中,长度为~10 ^ 6,[1] 3 5 7 9 11 13 15 17 19
,条目为有符号实数。
编辑: 我对性能感到好奇所以我做了我的第一个基准测试:
[1] 55
我测试了部分实际数据和较小的vec
(对于较大的k=1:1000
,所有algos因RAM问题而减速)。 Khashaa的算法是明显的赢家,并且还能够处理NAs。但是,根据akrun和mra68建议的答案,这可以通过> library(RcppRoll)
> library(zoo)
> library(microbenchmark)
>
> f <- Vectorize(function(x, k)RcppRoll::roll_sum(x, k), vectorize.args = "k")
> out = list()
> vec = na.omit(myrealdata)
> vec = vec[1:1e4]
> mb = microbenchmark(Khashaa = f(vec, 1:100),
+ mra68 = for(k in (1:100)){out[[k]] <- k*rollmean(vec, k)},
+ akrun = sapply(1:100, function(x) rollsum(vec, k=x)), times = 100)
> print(mb)
Unit: milliseconds
expr min lq mean median uq max neval
Khashaa 48.12953 49.08398 49.89553 49.55445 50.27705 53.23208 100
mra68 557.93112 564.74246 578.07404 568.95936 576.81239 858.52096 100
akrun 549.48471 556.68814 570.50853 560.17078 565.31508 1190.12545 100
来完成。谢谢你的答案!
答案 0 :(得分:6)
尝试
x <- 1:10
k <- 1:10
f <- Vectorize(function(x, k)RcppRoll::roll_sum(x, k), vectorize.args = "k")
f(x, k)
[[1]]
[1] 1 2 3 4 5 6 7 8 9 10
[[2]]
[1] 3 5 7 9 11 13 15 17 19
[[3]]
[1] 6 9 12 15 18 21 24 27
[[4]]
[1] 10 14 18 22 26 30 34
[[5]]
[1] 15 20 25 30 35 40
[[6]]
[1] 21 27 33 39 45
[[7]]
[1] 28 35 42 49
[[8]]
[1] 36 44 52
[[9]]
[1] 45 54
[[10]]
[1] 55
答案 1 :(得分:2)
由于平均值和总和密切相关,我们也可以使用&#39; rollmean&#39;来自动物园的功能&#39;包:
vec <- 1:10
for ( k in (1:10) ) { print(k*rollmean(vec,k)) }
根据需要输出:
[1] 1 2 3 4 5 6 7 8 9 10
[1] 3 5 7 9 11 13 15 17 19
[1] 6 9 12 15 18 21 24 27
[1] 10 14 18 22 26 30 34
[1] 15 20 25 30 35 40
[1] 21 27 33 39 45
[1] 28 35 42 49
[1] 36 44 52
[1] 45 54
[1] 55
这可能比“RcppRoll”解决方案更为基本。 我还使用大小为10 ^ 6的矢量检查了速度:
> vec <- sample(1000000) / 1000000
> k <- 1000
> system.time(for (i in (1:100)){ k*rollmean(vec,k)})/100
User System verstrichen
1.2972 0.0000 1.3075