【发布时间】:2020-06-18 04:10:41
【问题描述】:
我有一个具有以下结构的 data.table:
num_id value
1000 A1
1001 A1
1000 A2
1000 A3
1001 A54
1002 A55
1001 A100
想把它变成一个dt的形式
num_id A1 A2 A3 A54 A55 A100
1000 1 1 1 0 0 0
1001 1 0 0 1 0 1
1002 0 0 0 0 1 0
我认为使用dcast 会很容易。想到的公式是dcast(dt, numid~value) 但是抱怨Cross product of elements provided to CJ() would result in 4850158203 rows which exceeds .Machine$integer.max == 2147483647。这超过了预期的行数,因为我有大约 500,000 个唯一 ID。在较小的数据表上运行测试后,似乎对 dcast 的调用将 ID 保持原样,将 value 列替换为只有 1 个元素不为空的列向量。这没有多大帮助,因为缺少必要的聚合/分组步骤。
我编写了以下代码,该代码有效,但速度慢且令人费解。有没有办法在单个 dcast 调用中做到这一点?
futurecolumns=unique(dt$value)
aggregated=dt[,list(list(value)), by=num_id]
out=t(sapply(aggregated$V1, function(x){futurecolumns %in% x}))
out=as.data.table(out*1)
out$num_id=aggregated$num_id
setnames(out, c(futurecolumns, "num_id"))
【问题讨论】:
-
dcast(unique(dt), num_id ~ value, fun.aggregate=length)呢? -
您的建议中的
unique似乎可以删除dt中的重复行?那不是问题,没有重复的AFAIK。这给了我完全相同的错误和行为,即生成的 df 对于num_id和value的每个组合都有一行,而我想要一个 df 的行数与num_id中的唯一值一样多。 -
~500,000 个唯一
num_ids * 9700 个唯一values = 网格中的 4,850,000,000 个值。这对任何人都不会奏效。也许是一个稀疏矩阵,因为你会有这么多的 0? -
只有大约 500 个唯一的
values,所以最终的 df 尺寸应该是 500,000x500。
标签: r data.table reshape2