簡體   English   中英

R data.table中各組之間的相關性

[英]Correlation between groups in R data.table

如果這些值按組存儲在data.table的單個列中(而不是將data.table轉換為矩陣),是否有一種方法可以優雅地計算這些值之間的相關性?

library(data.table)
set.seed(1)             # reproducibility
dt <- data.table(id=1:4, group=rep(letters[1:2], c(4,4)), value=rnorm(8))
setkey(dt, group)

#    id group      value
# 1:  1     a -0.6264538
# 2:  2     a  0.1836433
# 3:  3     a -0.8356286
# 4:  4     a  1.5952808
# 5:  1     b  0.3295078
# 6:  2     b -0.8204684
# 7:  3     b  0.4874291
# 8:  4     b  0.7383247

可行,但需要輸入組名:

cor(dt["a"]$value, dt["b"]$value)
# [1] 0.1556371

我正在尋找更多類似的東西:

dt[, cor(value, value), by="group"]

但這並沒有給我帶來我想要的相關性。

對於具有正確結果的矩陣,這也是同樣的問題。

set.seed(1)             # reproducibility
m <- matrix(rnorm(8), ncol=2)
dimnames(m) <- list(id=1:4, group=letters[1:2])

#        group
# id           a          b
#   1 -0.6264538  0.3295078
#   2  0.1836433 -0.8204684
#   3 -0.8356286  0.4874291
#   4  1.5952808  0.7383247

cor(m)                  # correlations between groups

#           a         b
# a 1.0000000 0.1556371
# b 0.1556371 1.0000000

任何意見或幫助,不勝感激。

沒有簡單的方法可以使用data.table做到這data.table 您提供的第一種方法:

cor(dt["a"]$value, dt["b"]$value)

可能是最簡單的。

一種替代方法是將您的data.table"long"格式reshape"wide"格式:

> dtw <- reshape(dt, timevar="group", idvar="id", direction="wide")
> dtw
   id    value.a    value.b
1:  1 -0.6264538  0.3295078
2:  2  0.1836433 -0.8204684
3:  3 -0.8356286  0.4874291
4:  4  1.5952808  0.7383247
> cor(dtw[,list(value.a, value.b)])
          value.a   value.b
value.a 1.0000000 0.1556371
value.b 0.1556371 1.0000000

更新:如果您使用的data.table版本> = 1.9.0,則可以使用dcast.data.table代替, dcast.data.table更快。 檢查此帖子以獲取更多信息。

dcast.data.table(dt, id ~ group)

我不知道一種立即將其以矩陣形式獲取的方法,但是我發現此解決方案很有用:

dt[, {x = value; dt[, cor(x, value), by = group]}, by=group]

   group group        V1
1:     a     a 1.0000000
2:     a     b 0.1556371
3:     b     a 0.1556371
4:     b     b 1.0000000

因為您從熔融數據集開始,最后以相關性的熔融表示形式結束。

使用此表格,您還可以選擇只計算某些對,特別是浪費時間計算兩個非對角線。 例如:

 dt[, {x = value; g = group; dt[group <= g, list(cor(x, value)), by = group]}, by=group]
   group group        V1
1:     a     a 1.0000000
2:     b     a 0.1556371
3:     b     b 1.0000000

另外,對於兩個集合之間的互相關(即對角線遮擋),此形式也適用

library(data.table)
set.seed(1)             # reproducibility
dt1 <- data.table(id=1:4, group=rep(letters[1:2], c(4,4)), value=rnorm(8))
dt2 <- data.table(id=1:4, group=rep(letters[3:4], c(4,4)), value=rnorm(8))
setkey(dt1, group)
setkey(dt2, group)

dt1[, {x = value; g = group; dt2[, list(cor(x, value)), by = group]}, by=group]

   group group          V1
1:     a     c -0.39499814
2:     a     d  0.74234458
3:     b     c  0.96088312
4:     b     d  0.08016723

顯然,如果最終希望以矩陣形式使用dcast ,則可以使用dcastdcast.data.table ,但是請注意,在上面的示例中,您有兩列具有相同的名稱,要解決此問題,值得在其中重命名它們。 j功能。 對於原始問題:

dcast.data.table(dt[, {x = value; g1=group; dt[, list(g1, g2=group, c =cor(x, value)), by = group]}, by=group], g1~g2, value.var = "c")

   g1         a         b
1:  a 1.0000000 0.1556371
2:  b 0.1556371 1.0000000

從那以后,我找到了一個甚至更簡單的替代方法。 實際上,您的dt[, cor(value, value), by="group"]方法非常接近。 您真正需要的是首先對日期進行笛卡爾聯接,然后再分組。

dt[dt, allow.cartesian=T][, cor(value, value), by=list(group, group.1)]

這樣的好處是它將系列連在一起(而不是假設它們的長度相同)。 然后,您可以將其轉換為矩陣形式,或將其保留為在ggplot等圖中作為熱圖進行繪制。

完整的例子

setkey(dt, id)
c <- dt[dt, allow.cartesian=T][, list(Cor = cor(value, value.1)), by = list(group, group.1)]
c

   group group.1       Cor
1:     a       a 1.0000000
2:     b       a 0.1556371
3:     a       b 0.1556371
4:     b       b 1.0000000

dcast(c, group~group.1, value.var = "Cor")

  group         a         b
1     a 1.0000000 0.1556371
2     b 0.1556371 1.0000000

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM