我有一个包含两列的表格:
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
有什么想法吗?
答案 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])
})