【问题标题】:Find the most common combinations within each group in R在 R 中的每个组中查找最常见的组合
【发布时间】:2021-06-20 05:47:59
【问题描述】:

我有以下数据集,显示每个产品中包含的成分;

data <- data.frame("PRODUCT" = c("Creme","Creme","Creme","Creme","Medoc","Medoc","Medoc","Medoc","Medoc","Hububu","Hububu","Hububu","Hububu","Troll","Troll","Troll","Troll","Suzuki","Suzuki","Gluglu","Gluglu","Gluglu"), 
            "INGREDIENT" = c("zeze","zaza","zozo","zuzu","zaza","sasa","haha","zuzu","zemzem","zaza","zuzu","zizi","haha","zozo","zaza","zemzem","zuzu","sasa","zuzu","ozam","zaza","hayda"))

我想知道每种产品中最常见的成分组合;哪种成分与哪种其他成分有关?我应用了我在这个线程here 中找到的代码:

combinaisons_par_PRODUCT = data %>% 
  full_join(data, by="PRODUCT") %>% 
  group_by(INGREDIENT.x, INGREDIENT.y) %>% 
  summarise(n = length(unique(PRODUCT))) %>% 
  filter(INGREDIENT.x!=INGREDIENT.y) %>%
  mutate(item = paste(INGREDIENT.x, INGREDIENT.y, sep=", "))

它可以工作,但还有一个最后的缺陷;我希望订单被忽略。例如,这段代码会给我 1 个 HAHA 和 SASA 的关联,以及 1 个 SASA 和 HAHA 的关联。但对我来说,这些都是一样的。所以我希望代码忽略成分的顺序,并给我一个 2 HAHA 和 SASA 的唯一关联。

我尝试在应用代码之前对成分进行排序,但它也不起作用。有人可以帮我吗?我怎样才能有这些组合而不考虑顺序?

非常感谢!

【问题讨论】:

    标签: r associations combinations


    【解决方案1】:

    这是你想要的吗?我仅限于组合按字母顺序排列的情况,避免重复计数。

    data %>% 
      full_join(data, by="PRODUCT") %>%
      filter(INGREDIENT.x < INGREDIENT.y) %>%
      count(combo = paste(INGREDIENT.x, INGREDIENT.y, sep = ", "))
    

    【讨论】:

    • 是的,这似乎工作得很好,谢谢!
    【解决方案2】:

    使用graph_from_adjacency_matrixigraph 选项

    library(igraph)
    
    get.data.frame(
        graph_from_adjacency_matrix(
            crossprod(table(data)),
            mode = "undirected",
            weighted = TRUE
        )
    )
    

    给予

         from     to weight
    1    haha   haha      2
    2    haha   sasa      1
    3    haha   zaza      2
    4    haha zemzem      1
    5    haha   zizi      1
    6    haha   zuzu      2
    7   hayda  hayda      1
    8   hayda   ozam      1
    9   hayda   zaza      1
    10   ozam   ozam      1
    11   ozam   zaza      1
    12   sasa   sasa      2
    13   sasa   zaza      1
    14   sasa zemzem      1
    15   sasa   zuzu      2
    16   zaza   zaza      5
    17   zaza zemzem      2
    18   zaza   zeze      1
    19   zaza   zizi      1
    20   zaza   zozo      2
    21   zaza   zuzu      4
    22 zemzem zemzem      2
    23 zemzem   zozo      1
    24 zemzem   zuzu      2
    25   zeze   zeze      1
    26   zeze   zozo      1
    27   zeze   zuzu      1
    28   zizi   zizi      1
    29   zizi   zuzu      1
    30   zozo   zozo      2
    31   zozo   zuzu      2
    32   zuzu   zuzu      5
    

    【讨论】:

    • 非常感谢!我试过了,但我收到错误“get.data.frame 中的错误(graph_from_adjacency_matrix(crossprod(table(data)),:找不到“get.data.frame”
    • @SivaKg 对不起,我的错。您应该在我的代码前面添加library(igraph)。查看我的更新。
    【解决方案3】:

    我们可以使用base R

    m1 <- crossprod(table(data))
    subset(as.data.frame.table(m1 * lower.tri(m1, diag = TRUE)), Freq != 0)
    

    编辑:@ThomasIsCoding 的评论

    【讨论】:

    • crossprod 的好主意,点赞!顺便说一句,也许 mat &lt;- crossprod(table(data)); mat[upper.tri(mat)] &lt;- 0; out &lt;- subset(as.data.frame.table(mat), Freq != 0) 是 OP 想要的代码,因为 HAHA &amp; SASASASA &amp; HAHA 是同构的
    • @ThomasIsCoding 谢谢。我不确定预期的输出是什么。更新了帖子
    • 这确实是一个好主意,我喜欢作为交叉表的表示。但这是一个模拟数据。我的真实数据有 400 万行和数千种独特的成分。所以 R 不喜欢它 :( 但非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-05
    • 1970-01-01
    • 2017-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多