取R中唯一的行,但保留列中最常见的值,并使用层次结构来打破频率上的联系



我有一个数据帧,看起来像这样:

df <- data.frame(Set = c("A","A","A","B","B","B","B"), Values=c(1,1,2,1,1,2,2))

我想折叠数据帧,这样我有一行A和一行b。我想让这两行的Values列反映整个数据集中最常见的Values

我可以按照这里描述的那样做(如何找到统计模式?),但特别是当存在一个平局(两个值每个出现一次,因此没有"true")模式),它只取第一个值。

我更喜欢使用我自己的层次结构来确定在平局的情况下选择哪个值。

创建一个定义层次结构的数据框架,并为每种可能性分配一个数字分数。

hi <- data.frame(Poss = unique(df$Set), Nums =c(105,104))

在这种情况下,A获得的数值为105,B获得的数值为104(因此在平局的情况下,A将优先于B)。

将层次结构连接到原始数据帧。

require(dplyr)
matched <- left_join(df, hi, by = c("Set"="Poss"))

然后,在原始数据框中添加一个频率列,列出每个唯一的Set-Value组合出现的次数。

setDT(matched)[, freq := .N, by = c("Set", "Value")]

现在已经记录了这些频率,我们只需要每个Set-Value组合的一行,所以去掉其余的。

multiplied <- distinct(matched, Set, Value, .keep_all = TRUE)

现在,将频率乘以数字分数。

multiplied$mult <- multiplied$Nums * multiplied$freq

最后,首先按Set(升序)排序,然后按mult(降序)排序,并使用distinct()为每个Set中的每个Value取最高的数值分数。

check <- multiplied[with(multiplied, order(Set, -mult)), ]
final <- distinct(check, Set, .keep_all = TRUE)

这是有效的,因为B的多个实例(数值分数= 104)将被加在一起(3个实例将使B在mult列中的总分为312),但每当a和B以相同的频率出现时,a将胜出(105>104,210>208年,等等)。

如果使用不同于这里提供的数字分数,请确保它们与手头的数据集有足够的间隔。例如,对A使用2,对B使用1是行不通的,因为它需要3个B实例来胜过A,而不是2个。同样,如果您预计A和B的频率有很大差异,请使用1005和1004,因为A最终会以我上面使用的分数赶上B(200 * 104小于199 * 205)。

最新更新