5

我有以下数据表 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,即mode。所以预期的结果是

 a x 2
 b z 1

我可以绕一圈到达那里,但是有没有办法将序列号放在 id1 级别?或者一些这样的黑客可以让我有效和快速地做到这一点,也许是在上面显示的第一步?提前致谢

4

3 回答 3

7

我会这样做:

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.tableid1freqfreqby-without-bymult="last"

这将为每个分组节省一个sort步骤,随着组数量的增加,这可能会变得很耗时。请注意,这不处理关系。也就是说,如果您有id1两个相同的最大值,那么只会返回一个。

于 2013-08-14T22:51:54.177 回答
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”。而且,当然,您可以将表达式放在多行上,如果您愿意{},可以去掉's。;

于 2013-08-14T22:59:17.967 回答
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

关于查找模式的常见警告适用于此。这只是众多可能模式中的第一种。

于 2013-08-14T22:30:20.343 回答