【问题标题】:Cumulative Calculations (e.g. cumulative correlation) with data.table in RR中的data.table的累积计算(例如累积相关性)
【发布时间】:2015-08-26 08:34:56
【问题描述】:

在 R 中,我有一个包含两个测量值 redgreen 的 data.table,并且想计算它们的累积相关性。

library(data.table)
DT <- data.table(red   = c(1, 2, 3, 4, 5,  6.5, 7.6, 8.7),
                 green = c(2, 4, 6, 8, 10, 12,  14,  16),
                 id    = 1:8)

如何在一个 data.table 命令中获得以下输出?

...
> DT[1:5, cor(red, green)]
[1] 1                     # should go into row 5
> DT[1:6, cor(red, green)]
[1] 0.9970501             # should go into row 6, and so on ...
> DT[1:7, cor(red, green)]
[1] 0.9976889

编辑: 我知道它可以通过循环来解决,但是我的 data.table 有大约 100 万行分组为较小的块,所以循环相当慢,我认为可能还有其他可能性。

【问题讨论】:

  • data.table 有多大?

标签: r data.table


【解决方案1】:

基于我对类似问题here 的累积方差的回答,您可以找到累积协方差

library(dplyr) # for cummean
cum_cov <- function(x, y){
  n <- 1:length(x)
  res <- cumsum(x*y) - cummean(x)*cumsum(y) - cummean(y)*cumsum(x) + n*cummean(x)*cummean(y)
  res / (n-1)
}

cum_var <- function(x){# copy-pasted from previous answer
    n <- 1:length(x)
    (cumsum(x^2) - n*cummean(x)^2) / (n-1)
}

然后是累积相关性

cum_cor <- function(x, y) cum_cov(x, y)/sqrt(cum_var(x)*cum_var(y))
DT[, cumcor:=cum_cor(red, green),]
   red green id    cumcor
1: 1.0     2  1       NaN
2: 2.0     4  2 1.0000000
3: 3.0     6  3 1.0000000
4: 4.0     8  4 1.0000000
5: 5.0    10  5 1.0000000
6: 6.5    12  6 0.9970501
7: 7.6    14  7 0.9976889
8: 8.7    16  8 0.9983762

我希望它足够快

x <- rnorm(1e6)
y <- rnorm(1e6)+x
system.time(cum_cor(x, y))
#   user  system elapsed 
#  0.319   0.020   0.339 

【讨论】:

  • 哦,这个还是有点快,因为它直接建立在原始函数之上。我认为 Michele 的回答也适用于一般方法。
  • 如果速度不是问题,那么老 for loop 永远是你的朋友。
【解决方案2】:

创建一个cumcor 函数怎么样?

library(data.table)

DT <- data.table(red   = c(1, 2, 3, 4, 5,  6.5, 7.6, 8.7),
                 green = c(2, 4, 6, 8, 10, 12,  14,  16),
                 id    = 1:8)

cumcor <- function(x, y, start = 5, ...) {
    c(rep(NA, start - 1), sapply(start:length(x), function(k) cor(x[1:k], y[1:k]), ...))
}

DT[, list(red, green, cumcor = cumcor(red, green))]
   red green    cumcor
1: 1.0     2        NA
2: 2.0     4        NA
3: 3.0     6        NA
4: 4.0     8        NA
5: 5.0    10 1.0000000
6: 6.5    12 0.9970501
7: 7.6    14 0.9976889
8: 8.7    16 0.9983762

请注意上面的cumcor函数在开始时需要更多的QC(xy具有相同的长度,start大于0,等等)

【讨论】:

  • 谢谢 - 简单的解决方案通常是最好的(比如 cumsum() 与 sum())。我最初希望有一些 data.table-internal 的东西(使用这些 .N 和 shift() - 运算符),但这工作得很好,并且非常易读和清晰。
猜你喜欢
  • 1970-01-01
  • 2017-03-17
  • 1970-01-01
  • 2016-02-19
  • 1970-01-01
  • 1970-01-01
  • 2019-06-06
  • 1970-01-01
  • 2021-02-02
相关资源
最近更新 更多