我有交易数据,我需要从中创建一个关联矩阵。我尝试过自动加入,但似乎没有任何效果。下面是示例代码和所需的输出。我正在寻找使用R中的数据表的解决方案
> TP <- data.table(
Tr = c("T1","T1","T2","T2","T2", "T3", "T4"),
Pr = c("P1","P2","P3","P1","P4", "P2", "P9")
)
> TP
Tr Pr
1: T1 P1
2: T1 P2
3: T2 P3
4: T2 P1
5: T2 P4
6: T3 P2
7: T4 P9
所需的输出是:
T1 T2 T3 T4
1: 1 1 0 0
2: 1 0 1 0
3: 1 0 0 0
4: 0 1 0 0
5: 0 0 0 1
或者如果可能得到类似的东西甚至更好。
Pr T1 T2 T3 T4
1: P1 1 1 0 0
2: P2 1 0 1 0
3: P3 1 0 0 0
4: P4 0 1 0 0
5: P9 0 0 0 1
答案 0 :(得分:1)
这应该有效:
dcast(TP, Pr ~ Tr, fun.aggregate = function(x){(length(x) > 0) * 1})
Using 'Pr' as value column. Use 'value.var' to override
Pr T1 T2 T3 T4
1: P1 1 1 0 0
2: P2 1 0 1 0
3: P3 0 1 0 0
4: P4 0 1 0 0
5: P9 0 0 0 1
如果我们没有重复的关联,则@David Arenburg的建议要干净得多:
dcast(TP, Pr ~ Tr, length)
答案 1 :(得分:1)
我会按照David Arenburg的建议用dcast()
来做到这一点,但这是(一种快速的)另一种有趣的选择:
TP[, data.table(unclass(table(Pr, Tr)), keep.rownames = "Pr")]
Pr T1 T2 T3 T4
1: P1 1 1 0 0
2: P2 1 0 1 0
3: P3 0 1 0 0
4: P4 0 1 0 0
5: P9 0 0 0 1
基准:
在处理数百万行dcast()
时,速度似乎更快:
TP1 <- data.table(
Tr = paste0("T", sample(1:10, size = 1e5, replace = TRUE)),
Pr = paste0("P", sample(1:1e4, size = 1e5, replace = TRUE))
)
TP_huge <- data.table(
Tr = paste0("T", sample(1:10, size = 1e7, replace = TRUE)),
Pr = paste0("P", sample(1:1e4, size = 1e7, replace = TRUE))
)
microbenchmark::microbenchmark(
table1 = TP1[, data.table(unclass(table(Pr, Tr)), keep.rownames = "Pr")],
dcast1 = dcast(TP1, Pr ~ Tr, length, value.var = "Pr"),
table_huge = TP_huge[, data.table(unclass(table(Pr, Tr)), keep.rownames = "Pr")],
dcast_huge = dcast(TP_huge, Pr ~ Tr, length, value.var = "Pr"),
times = 5
)
Unit: milliseconds
expr min lq mean median uq max neval cld
table1 92.71867 105.8366 127.4707 124.4188 150.0642 164.3155 5 a
dcast1 255.53793 271.5194 292.2005 301.4840 302.5010 329.9600 5 b
table_huge 1719.83678 1732.1086 1771.0142 1733.8847 1771.5087 1897.7325 5 d
dcast_huge 917.94755 927.1657 971.4084 986.1038 998.1780 1027.6468 5 c