【问题标题】:Create a time series using diagonal matrices使用对角矩阵创建时间序列
【发布时间】:2020-04-29 20:39:21
【问题描述】:

假设我的数据具有以下结构:

structure(list(Year = c(2000, 2000, 2000, 2000, 2000, 2000, 2000, 
2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 
2000, 2000, 2001, 2001, 2001, 2001), Month = c(1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), Day = c(1, 
1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 1, 1, 
1, 1), FivMin = c(1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 
4, 1, 2, 3, 4, 1, 2, 3, 4), A = c(1, 2, 3, 0, 1, 5, 3, 4, 1, 
0, 3, 1, 0, 2, 3, 0, 1, 2, 0, 9, 1, 2, 3, 0), B = c(2, 3, 4, 
1, 2, 3, 0, 1, 2, 1, 4, -2, 2, 1, 0, 2, 2, 3, -1, 1, 2, 3, 4, 
1), C = c(3, 0, 1, 2, 3, 4, 1, 9, 3, 7, 1, 2, 3, 4, 1, 2, 3, 
4, 1, 2, 3, 0, 1, 2), D = c(4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 
3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3)), row.names = c(NA, -24L
), class = c("tbl_df", "tbl", "data.frame"))

我的想法是每天使用crossproduct 命令。为此,我编写了以下代码:

res <- lapply(split(data, data[c("Year","Month","Day")]), 
          function(x) tcrossprod(t(x[c("A","B","C","D")])))
Final<-do.call(rbind, lapply(res, diag))

Final 的输出是:

          A  B   C  D
2000.1.1 14 30  14 30
2001.1.1 14 30  14 30
2000.1.2 51 14 107 30
2001.1.2  0  0   0  0
2000.1.3 11 25  63 30
2001.1.3  0  0   0  0
2000.1.4 13  9  30 30
2001.1.4  0  0   0  0
2000.1.5 86 15  30 30
2001.1.5  0  0   0  0 

我需要的是由crossproduct计算的对角线形成的时间序列(矩阵或df对象),这意味着我想要的时间序列是

          A  B   C  D
2000.1.1 14 30  14 30
2000.1.2 51 14 107 30
2000.1.3 11 25  63 30
2000.1.4 13  9  30 30
2000.1.5 86 15  30 30
2001.1.1 14 30  14 30

我的原始代码会有什么变化。我认为我可以用grouped_by 替换split 命令,但它不起作用。

【问题讨论】:

  • 您可以使用as.matrix 将看起来像矩阵的data.frame 转换为矩阵。一旦你有了矩阵,你就可以做线性代数了。有crossprod%*%diag等。例如见datascienceplus.com/linear-algebra-in-r
  • @asac,我需要每天计算crossprod,因为我需要创建一个ts。如果我只使用一个矩阵的 crossprod,我将不会得到每个变量的时间序列
  • 您可以在tcrossprod 输出上应用diagres &lt;- lapply(split(data, data[c("Year","Month","Day")]), function(x) diag(tcrossprod(t(x[c("A","B","C","D")])))); ans &lt;- do.call(rbind, res); ans[order(rownames(ans)), ]

标签: r dataframe time-series


【解决方案1】:

由于拆分使数据框成为列表,它也创建了 0 行。只需删除那些零行并尝试。

ls<- split(data, data[c("Year","Month","Day")])
ls<- ls[sapply(ls, nrow)>0]
res <- lapply(ls, function(x) tcrossprod(t(x[c("A","B","C","D")])))
Final<-do.call(rbind, lapply(res, diag))
Final <- Final[ order(row.names(Final)), ]
Final

输出:

          A  B   C  D
2000.1.1 14 30  14 30
2000.1.2 51 14 107 30
2000.1.3 11 25  63 30
2000.1.4 13  9  30 30
2000.1.5 86 15  30 30
2001.1.1 14 30  14 30

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-15
    • 1970-01-01
    • 2011-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多