如何使用 data.table 找到组之间的线性回归?
How to find linear regression between groups using data.table?
我试图找到以下数据集的所有可用组之间的线性回归。
library(data.table)
dt <- data.table(time = c(rep(rep(1:100, times = 1), 4), rep(1:30, times = 1)),
group = c(rep(c("a","b","c","d"), each = 100), rep("e", 30)),
value = rnorm(430))
dt[]
time group value
1: 1 a 0.1625954
2: 2 a -1.2288462
3: 3 a -0.1628570
4: 4 a 1.0597886
5: 5 a -1.1828334
---
426: 26 e -1.3762654
427: 27 e 0.3761436
428: 28 e -1.6982330
429: 29 e 0.1940263
430: 30 e -0.4631258
输出应该类似于
group1 group2 regression
a b 1.2
a c 0.3
b c 0.5
d a 4.3
...
我正在寻找仅使用 data.table 库的解决方案。
- 应该找到所有组的组合的线性回归。这包括案例
a~b
和 b~a
,因为每个案例的回归都会不同。
- 由于某些组的大小不同,因此应使用时间变量来查找任何一组组之间的公共行。
- 解决方案将需要找到组的所有组合。
有了新数据,我们可以split
将数据'group'变成list
。然后,在list
的names
上使用combn
进行两两组合,提取出list
个元素(s1
,s2
),检查是否有 any
常见 'time' (intersect
)。使用基于 length
的条件,即如果有共同元素,则在相应的 'value' 列上应用 lm
,创建一个 data.table 并汇总 coef
使用组名称和 rbind
list
元素
library(data.table)
lst1 <- split(dt, dt$group)
rbindlist(combn(names(lst1), 2, FUN = function(x) {
s1 <- lst1[[x[1]]]
s2 <- lst1[[x[2]]]
i1 <- intersect(s1$time, s2$time)
if(length(i1) > 0) na.omit(s1[s2, on = .(time)][,
. (group1 = first(s1$group), group2 = first(s2$group),
regression = lm(i.value ~ value)$coef[2])])
else
data.table(group1 = first(s1$group), group2 = first(s2$group),
regression = NA_real_)}, simplify = FALSE))
-输出
group1 group2 regression
1: a b 0.03033996
2: a c 0.06391242
3: a d -0.09138112
4: a e -0.27738183
5: b c 0.05663270
6: b d 0.05481604
7: b e 0.27789495
8: c d -0.13987978
9: c e 0.16388299
10: d e 0.12380720
如果我们想要完整的组合,请使用 expand.grid
或 CJ
(来自 data.table
dt2 <- CJ(group1 = names(lst1), group2 = names(lst1))[group1 != group2]
dt2[, rbindlist(Map(function(x, y) {
s1 <- lst1[[x]]
s2 <- lst1[[y]]
i1 <- intersect(s1$time, s2$time)
if(length(i1) > 0) na.omit(s1[s2, on = .(time)][,
data.table(group1 = x, group2 = y,
regresion = lm(i.value ~ value)$coef[2])]) else
data.table(group1 = x, group2 = y, regression = NA_real_)
}, group1, group2))]
-输出
group1 group2 regresion
1: a b 0.03033996
2: a c 0.06391242
3: a d -0.09138112
4: a e -0.27738183
5: b a 0.03247826
6: b c 0.05663270
7: b d 0.05481604
8: b e 0.27789495
9: c a 0.07488082
10: c b 0.06198333
11: c d -0.13987978
12: c e 0.16388299
13: d a -0.09295215
14: d b 0.05208743
15: d c -0.12144302
16: d e 0.12380720
17: e a -0.25136439
18: e b 0.34052322
19: e c 0.28677255
20: e d 0.21435666
我试图找到以下数据集的所有可用组之间的线性回归。
library(data.table)
dt <- data.table(time = c(rep(rep(1:100, times = 1), 4), rep(1:30, times = 1)),
group = c(rep(c("a","b","c","d"), each = 100), rep("e", 30)),
value = rnorm(430))
dt[]
time group value
1: 1 a 0.1625954
2: 2 a -1.2288462
3: 3 a -0.1628570
4: 4 a 1.0597886
5: 5 a -1.1828334
---
426: 26 e -1.3762654
427: 27 e 0.3761436
428: 28 e -1.6982330
429: 29 e 0.1940263
430: 30 e -0.4631258
输出应该类似于
group1 group2 regression
a b 1.2
a c 0.3
b c 0.5
d a 4.3
...
我正在寻找仅使用 data.table 库的解决方案。
- 应该找到所有组的组合的线性回归。这包括案例
a~b
和b~a
,因为每个案例的回归都会不同。 - 由于某些组的大小不同,因此应使用时间变量来查找任何一组组之间的公共行。
- 解决方案将需要找到组的所有组合。
有了新数据,我们可以split
将数据'group'变成list
。然后,在list
的names
上使用combn
进行两两组合,提取出list
个元素(s1
,s2
),检查是否有 any
常见 'time' (intersect
)。使用基于 length
的条件,即如果有共同元素,则在相应的 'value' 列上应用 lm
,创建一个 data.table 并汇总 coef
使用组名称和 rbind
list
元素
library(data.table)
lst1 <- split(dt, dt$group)
rbindlist(combn(names(lst1), 2, FUN = function(x) {
s1 <- lst1[[x[1]]]
s2 <- lst1[[x[2]]]
i1 <- intersect(s1$time, s2$time)
if(length(i1) > 0) na.omit(s1[s2, on = .(time)][,
. (group1 = first(s1$group), group2 = first(s2$group),
regression = lm(i.value ~ value)$coef[2])])
else
data.table(group1 = first(s1$group), group2 = first(s2$group),
regression = NA_real_)}, simplify = FALSE))
-输出
group1 group2 regression
1: a b 0.03033996
2: a c 0.06391242
3: a d -0.09138112
4: a e -0.27738183
5: b c 0.05663270
6: b d 0.05481604
7: b e 0.27789495
8: c d -0.13987978
9: c e 0.16388299
10: d e 0.12380720
如果我们想要完整的组合,请使用 expand.grid
或 CJ
(来自 data.table
dt2 <- CJ(group1 = names(lst1), group2 = names(lst1))[group1 != group2]
dt2[, rbindlist(Map(function(x, y) {
s1 <- lst1[[x]]
s2 <- lst1[[y]]
i1 <- intersect(s1$time, s2$time)
if(length(i1) > 0) na.omit(s1[s2, on = .(time)][,
data.table(group1 = x, group2 = y,
regresion = lm(i.value ~ value)$coef[2])]) else
data.table(group1 = x, group2 = y, regression = NA_real_)
}, group1, group2))]
-输出
group1 group2 regresion
1: a b 0.03033996
2: a c 0.06391242
3: a d -0.09138112
4: a e -0.27738183
5: b a 0.03247826
6: b c 0.05663270
7: b d 0.05481604
8: b e 0.27789495
9: c a 0.07488082
10: c b 0.06198333
11: c d -0.13987978
12: c e 0.16388299
13: d a -0.09295215
14: d b 0.05208743
15: d c -0.12144302
16: d e 0.12380720
17: e a -0.25136439
18: e b 0.34052322
19: e c 0.28677255
20: e d 0.21435666