我有以下数据表x
id1 id2
a x
a x
a y
b z
对于id1,id2的每个组合,我可以通过以下方式找到实例数
x[,list(
freq = .N
),by = "id1,id2"]
上面会产生
a x 2
a y 1
b z 1
接下来我想找到每个id1最常见的id2,即模式。所以预期的结果是
a x 2
b z 1
我可以通过一轮方式到达那里,但有没有办法将序列号放在id1级别?或者某些这样的黑客攻击让我有效而迅速,也许是在上面显示的第一步? 提前致谢
答案 0 :(得分:4)
我这样做:
setkey(dt[, list(freq = .N), by=list(id1, id2)],
id1, freq)[J(unique(id1)), mult="last"]
id1 id2 freq
1: a x 2
2: b z 1
我们的想法是首先获得freq
列(就像你一样)。然后setkey
生成data.table
列id1
和freq
。这已经按升序排序freq
了。有了这个,我们就可以进行by-without-by
子集化并将其与mult="last"
结合起来(因为对于每个组,最后一个值将是最大值,因为它按升序排序)。
这将为每个分组保存sort
步骤,随着群组数量的增加可能会耗费大量时间。请注意,这不会处理关系。也就是说,如果你有相同的id1
两个相等的最大值,那么只返回一个。
答案 1 :(得分:2)
我会使用table
:
x[,{t=table(id2);r=which.max(t);list(names(t)[r],t[r])},by=id1]
给出了
id1 V1 V2
1: a x 2
2: b y 1
您可以将名称插入上面的list(...
部分,以替换“V1”和“V2”。当然,如果您愿意,可以将{}
表达式放在多行上并删除;
。
答案 2 :(得分:1)
x[,list(
freq = sort(table(id2),decreasing=TRUE)[1]
),by = "id1"]
id1 freq
1: a 2
2: b 1
x[,list(names_mode=names(sort(table(id2),decreasing=TRUE)[1]),
max_freq_id2 = sort(table(id2),decreasing=TRUE)[1]
),by = "id1"]
id1 names_mode max_freq_id2
1: a x 2
2: b z 1
关于寻找模式的常见警告适用于此处。这只是许多可能模式中的第一种。