2

我有一个有两列的表:

aaa     bbb
a1      b2
a1      b6
a1      b2
a1      b2
a1      b5
a1      b6
a2      b2
a2      b2
a2      b2
a2      b6
a2      b6
a2      b5

这些列都不应被视为已排序。我想做的是找到最优雅的方法来计算存在多少 aaa,bbb 给定 aaa 的组合,然后取最流行的组合(例如 100 个)并减去所有剩余组合的总和(例如 10 个),即预计会低于流行的。输出应该是元素 aaa 和这两个数字之间的差。例如,上面的输出应该如下:

var     cnt
a1      0
a2      0

有任何想法吗?

4

2 回答 2

5

这是一种使用方法data.table

require(data.table)
DT <- data.table(df) # where df is your data.frame
setkey(DT[, .N, by=list(aaa, bbb)], aaa, N)[, list(cnt = 
                                      N[.N]-sum(N[-.N])), by=aaa]

   aaa cnt
1:  a1   0
2:  a2   0

这个想法是首先获得每个组合的计数。这是通过以下方式完成的:

OUT <- DT[, .N, by = list(aaa, bbb)]
# which gives you: 
   aaa bbb N
1:  a1  b2 3
2:  a1  b6 2
3:  a1  b5 1
4:  a2  b2 3
5:  a2  b6 2
6:  a2  b5 1

在此之后,我们在aaaNsetkey列上,默认情况下会对它们进行排序(这是在此处设置键的唯一目的)。

OUT <- setkey(DT[, .N, by=list(aaa, bbb)], aaa, N)
# which gives you:
  aaa bbb N
1:  a1  b5 1
2:  a1  b6 2
3:  a1  b2 3
4:  a2  b5 1
5:  a2  b6 2
6:  a2  b2 3

现在它已排序,我们可以按列aaa拆分/分组并获得最终的cnt列。由于N已排序,因此最大值将始终是最后一个。因此,我们取最后一个值N[.N]并用剩余值的总和减去它,N[-.N]同时按列aaa分组。这是最后一部分:

OUT[, list(cnt = N[.N]-sum(N[-.N])), by=aaa]

完成。您可以将所有这些命令链接在一起(就像我所做的那样),或者您可以将它们分成单独的步骤(正如我为了解释而展示的那样)。这是你的选择。

注意:如果aaa, bbb的 1 个以上组合出现相同的最大值,这将导致负值。

于 2013-08-09T11:54:19.017 回答
4

您需要考虑如何打破关系。以下解决方案不处理此问题,即假设没有联系。

library(plyr)
#use ddply to split-apply-combine according to aaa values
ddply(DF, .(aaa), function(d) {
  #sort bbb and calculate run lengths
  nums <- rle(sort(as.character(d$bbb)))
  #maximum run length
  mnum <- max(nums$lengths) 
  #the desired difference
  mnum - sum(nums$lengths[nums$lengths!=mnum])
})
于 2013-08-09T11:52:42.757 回答