检查R中的匹配项

时间:2013-08-09 11:38:45

标签: r matching

我有一个包含两列的表格:

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

有什么想法吗?

2 个答案:

答案 0 :(得分: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

在此之后,我们setkey aaa N ,它们会默认对它们进行排序(这是设置密钥的唯一目的)

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],并在按 aaa 列分组时使用剩余值N[-.N]的总和减去它。这是最后一部分:

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

实现。你可以将所有这些命令链接在一起(就像我已经完成的那样),或者你可以将它们分成不同的步骤(正如我为解释所示)。这是你的选择。

注意:如果超过1个 aaa,bbb 的组合出现相同的最大值,则会产生负值。

答案 1 :(得分: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])
})