0

我有 3 列数据,每列 10 行,如下所示

set.seed(101)
inputx <- rnorm(1000,mean = 3,sd=2)
inputy <- rnorm(1000,mean = 2,sd=1)
inputz <- rnorm(1000,mean = 1,sd=3)
example <- cbind(inputx,inputy,inputz)

    > head(example,10)
        inputx      inputy     inputz
 [1,] 2.347927  2.50319581  4.4931430
 [2,] 4.104924 -0.09747067 -0.2836938
 [3,] 1.650112  1.90551542  0.9146087
 [4,] 3.428719  3.01454241  4.9332929
 [5,] 3.621538  1.92059955  2.4220865
 [6,] 5.347933  1.74487106  2.9122764
 [7,] 4.237580  2.78095054  7.8622898
 [8,] 2.774531  3.20741266 -1.5977934
 [9,] 4.834057  1.09214734 -0.5482315
[10,] 2.553481  0.59679215  0.5285020

我的实际数据总共有 10 个变量,但为简单起见,我只使用了 3 个。

对于下面的每个排列,我想使用大小为 4 的滚动窗口来计算 ccf

    inputx,inputx
    inputx,inputy
    inputx,inputz
    inputy,inputx
    inputy,inputy
    inputy,inputz
    inputz,inputx
    inputz,inputy
    inputz,inputz

例如

ccf(example[1:4,1],example[1:4,2]) 
ccf(example[2:5,1],example[2:5,2])
.
.
.
ccf(example[7:10,1],example[7:10,2])

如您所见,上面的示例仅适用于第 1 列和第 2 列,但我希望使用滚动窗口方法对所有列都执行此操作。

滚动窗口过程很容易使用 rollapply 函数来处理,您可以在其中指定窗口的大小,并将 by.column 指定为 FALSE,这样它就不会分别在每一列上应用该函数。

如果我想对每一列滚动应用诸如 mean 之类的函数,我可以这样做,但是所有组合的列之间的循环让我大吃一惊,我无法弄清楚。

test <- rollapply(example[,c(1,2)],4,mean, by.column=TRUE)

对于输出,ccf 结果应按行存储,并且尺寸应为 10x9,因为原始数据中有 10 行,ccf 函数有 9 个排列。输出的前 3 行将是 NA,因为滚动窗口使用的大小为 4。下面的值仅用于说明目的,并不是真正的输出值。

输出->

     xx  xy  xz  yx  yy  yz  zx  zy  zz
[1,] NA  NA  NA  NA  NA  NA  NA  NA  NA  
[2,] NA  NA  NA  NA  NA  NA  NA  NA  NA 
[3,] NA  NA  NA  NA  NA  NA  NA  NA  NA  
[4,] .1  .2  .3  .2  .8  .5  .3  .5  .9 
[5,] .1  .2  .3  .2  .8  .5  .3  .5  .9  
[6,] .1  .2  .3  .2  .8  .5  .3  .5  .9 
[7,] .1  .2  .3  .2  .8  .5  .3  .5  .9  
[8,] .1  .2  .3  .2  .8  .5  .3  .5  .9 
[9,] .1  .2  .3  .2  .8  .5  .3  .5  .9  
[10,].1  .2  .3  .2  .8  .5  .3  .5  .9 

我会很感激在所有排列中应用循环的一点帮助,我想如果我得到了,我可以做 rollapply 包装器来实现滑动窗口。

4

3 回答 3

1

1) ccf(x, y)两个 4 向量xy给出一个 7 向量,因此输出将有 3 * 3 * 7 = 63 列,而不是 9,如问题中所述。

在评论中,张贴者说可以用另一个函数代替ccf下面的假设cov(x, y),因为它输出一个标量而不是一个 7 向量,因此会给出一个 10 x 9 的输出。在这种特殊情况下cov(cbind(x, y, z)),会产生一个 3x3 矩阵,将其展平后会产生一个 9 向量。

rollapplyr(head(example, 10), 4, function(x) c(cov(x)), fill = NA, by.column = FALSE)

给出以下 10x9 矩阵:

           [,1]        [,2]       [,3]        [,4]      [,5]       [,6]       [,7]       [,8]      [,9]
 [1,]        NA          NA         NA          NA        NA         NA         NA         NA        NA
 [2,]        NA          NA         NA          NA        NA         NA         NA         NA        NA
 [3,]        NA          NA         NA          NA        NA         NA         NA         NA        NA
 [4,] 1.1990739 -0.72070179 -0.3951435 -0.72070179 1.8590569  3.1565993 -0.3951435  3.1565993  6.718376
 [5,] 1.1503463 -0.51712419  0.1548365 -0.51712419 1.6830055  2.6102211  0.1548365  2.6102211  5.058550
 [6,] 2.2854029 -0.12857123  1.1658204 -0.12857123 0.3413027  0.7821381  1.1658204  0.7821381  2.753662
 [7,] 0.7473036 -0.31336885 -0.2743693 -0.31336885 0.3923239  1.1959920 -0.2743693  1.1959920  6.109035
 [8,] 1.1727627 -0.53344663  2.2960862 -0.53344663 0.4851109 -0.5067012  2.2960862 -0.5067012 15.027672
 [9,] 1.2381071 -0.88053417  1.5728089 -0.88053417 0.9289009  0.7283704  1.5728089  0.7283704 18.179175
[10,] 1.2353345 -0.05021654  1.7008923 -0.05021654 1.6116281  1.4902571  1.7008923  1.4902571 18.399713

2)或给出相同结果的this:

k <- ncol(example)
g <- expand.grid(1:k, 1:k)
Cov <- function(x) apply(g, 1, function(ix) cov(x[, ix[1]], x[, ix[2]]))
rollapplyr(head(example, 10), 4, Cov, by.column = FALSE, fill = NA)

请注意,在这种情况下,cov它会产生一个对称矩阵(3 个下三角值等于 3 个上三角值),因此我们可能只希望输出对角线和上三角部分,如果是这种情况,我们可以使用upper.tri它来对其进行子集化。

于 2017-08-09T12:49:42.643 回答
0

我真的无法说出你想要达到的目标。我没有rollapply在基础 R 中看到该函数,但我知道您可以使用该combn函数:我将为您提供上述示例的所有 4 个窗口组合,但仅提供 10 个数字。我无法生成 1000 个数字,但您可以更改代码来执行此操作。

  set.seed(101)
  inputx <- rnorm(10,mean = 3,sd=2)
  inputy <- rnorm(10,mean = 2,sd=1)
  inputz <- rnorm(10,mean = 1,sd=3)
  example <- cbind(inputx,inputy,inputz)# Has only 10 rows. just for illustration

 a=lapply(1:(nrow(example)-3),function(x) x:(x+3))# all the four window combinations
 Map(combn,ncol(example),2,c(function(x,y) example[y,x]),y=a)

上面的代码为您提供了按您想要的方式分解的整个数据。然后,您可以随意操作它。如果这有帮助,请告诉我们。谢谢

于 2017-08-09T00:58:45.947 回答
0

用于expand.grid生成组合列表。然后您可以执行以下操作:

combos <- expand.grid(colnames(example), colnames(example), stringsAsFactors=F)

sapply(1:nrow(combos), function(j) {
    MY_CALCULATION
})
于 2017-08-09T00:51:25.390 回答