寻找最常见的组合

4
我有一个包含两个列的数据框,分别是ID编号和品牌:
X1     X2
1234   A89
1234   A87
1234   A87
1234   A32
1234   A27
1234   A27
1235   A12
1235   A14
1235   A14
1236   A32
1236   A32
1236   A27
1236   A12
1236   A12
1236   A14
1236   A89
1236   A87
1237   A99
1237   A98

我要找到最常出现的三个品牌组合,与id号相关:
A89, A87
A32, A27
A12, A14

我尝试过: library(dplyr)
 df %>% 
  group_by(X1,X2) %>%
  mutate(n = n()) %>%
  group_by(X1) %>%
  slice(which.max(n)) %>%
  select(-n)

但它无法正确工作。我会感激任何想法或建议!

4个回答

3
这里有一种基于R语言的方法。我们以X1为分组依据,对X2进行分割,并获取每个子组的两个值的组合。然后,我们获取三个最常见的组合。
with(data.frame(table(unlist(lapply(split(df$X2, df$X1), function(x)
    combn(unique(x), min(2, length(x)), paste, collapse = "-"))))),
    as.character(Var1[head(order(Freq, decreasing = TRUE), 3)]))
#[1] "A12-A14" "A32-A27" "A89-A87"

数据

df = structure(list(X1 = c(1234L, 1234L, 1234L, 1234L, 1234L, 1234L, 
1235L, 1235L, 1235L, 1236L, 1236L, 1236L, 1236L, 1236L, 1236L, 
1236L, 1236L, 1237L, 1237L), X2 = c("A89", "A87", "A87", "A32", 
"A27", "A27", "A12", "A14", "A14", "A32", "A32", "A27", "A12", 
"A12", "A14", "A89", "A87", "A99", "A98")), .Names = c("X1", 
"X2"), class = "data.frame", row.names = c(NA, -19L))

我尝试了这个,但是在处理完整数据集时遇到了问题。我收到了错误信息“Error in combn(unique(x), 2, paste, collapse = "-") : n < m”。我不太确定出了什么问题。 - anrpet
意译为:我知道这已经有些过时,但我一直在改进它并遇到了相同的问题-为了让其他人受益,你需要至少有两个唯一的X2值(原始帖子中的“品牌”),以便每个分组变量(原始帖子中的X1)都有数据。你可以通过最初使用df = df[sapply(df, function(x) length(unique(x))) > 1]进行子集划分来实现这一点。 - Mike S

2

我不建议使用which.max,而是坚持使用标准的dplyr

library(dplyr)

df %>% 
  group_by(X1,X2) %>%
  mutate(n = n()) %>%
  group_by(X2) %>% # or X1? Unclear which is your sorting variable
  top_n(3, X2) %>% # Returns 3 rows for each, can be changed / also could be X1
  select(-n)

注意:top_n 如果存在并列的情况,将包括超过 3 行。

2

这里有另一种使用基本R方法的技巧,它使用tapply进行分组,并使用combnpaste获取成对组合。

names(tail(sort(table(unlist(tapply(df$X2, df$X1,
                                FUN=function(x) combn(unique(x), 2, paste, collapse="-"))))),
           3))
[1] "A12-A14" "A32-A27" "A89-A87"

combn(unique(x), 2, paste, collapse="-")函数将向量x中的唯一值两两组合,并将它们拼接在一起。tapply函数按组执行此操作并返回一个列表。 unlist函数将其转换为向量,table函数计算频率。这些频率按从小到大排序,我们使用tail函数获取最后3个。 names函数从table中提取对而不是计数。


这对于我的较小数据集有效,但对于较大的数据集则无效,因为出现了错误n < m。我怀疑我需要为长度小于“m”的情况添加一个异常处理...你觉得呢? - anrpet
我的猜测是这个消息来自于combn,所以你可以将 function(x) combn(unique(x), 2, paste, collapse="-") 改为 function(x) if(length(x) > 1) combn(unique(x), 2, paste, collapse="-") else NA,这样就不会出现错误了。 - lmo

0
一个替代方案。首先,我们按组(X1)生成所有2个X2的组合,然后使用dplyr进行聚合和子集化,选择前3个。
combinations = as.data.frame(do.call(rbind,lapply(split(df,df$X1), function(x) 
    {t(combn(unique(x$X2),2))})))

combinations %>% 
group_by(V1,V2) %>% 
summarize(n=n()) %>% 
arrange(-n) %>% 
.[1:3,]

输出:

# A tibble: 3 x 3
# Groups:   V1 [3]
      V1     V2     n
  <fctr> <fctr> <int>
1    A12    A14     2
2    A32    A27     2
3    A89    A87     2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接