【问题标题】:Count Combinations across groups in RR中跨组的计数组合
【发布时间】:2018-11-14 17:12:10
【问题描述】:

我的数据设置为

df=data.frame(ID=c('A', 'A','A','B','B','C','C','C', 'C', 'C','D', 'E', 'E'),
                    drink_freq = c('Coffee Light', 'Water Heavy', 'Tea Medium',
                                   'Coffee Medium', 'Water Light', 
                                   'Espresso Light', 'Coffee Medium', 'Water Light', 'Soda Light', 'Tea Medium',
                                   'Coffee Heavy',
                                   'Coffee Medium', 'Soda Light'))

我想做的是创建某种列联表,显示用户可能属于的不同细分市场的组合频率。例如... Soda Light-Coffee Medium 和 Coffee Medium-Water Light 为 2,而 Coffee Light-Water Heavy 为 1。

我觉得这并不难,但我在编写代码时遇到了麻烦,因为用户可以属于不同数量的组。

【问题讨论】:

  • 你可以用table检查combh
  • 我现在正在查找 combn 文档,但我不确定我是否了解如何将它与 table 一起使用。你能详细说明一下吗?
  • 没有预期的输出,不清楚

标签: r dplyr tidyverse tidyr data-manipulation


【解决方案1】:

这是一个tidyverse 解决方案,它创建了所有独特的饮料组合(即考虑了饮料的顺序)并计算了他们拥有多少共同用户:

df=data.frame(ID=c('A', 'A','A','B','B','C','C','C', 'C', 'C','D', 'E', 'E'),
              drink_freq = c('Coffee Light', 'Water Heavy', 'Tea Medium',
                             'Coffee Medium', 'Water Light', 
                             'Espresso Light', 'Coffee Medium', 'Water Light', 'Soda Light', 'Tea Medium',
                             'Coffee Heavy',
                             'Coffee Medium', 'Soda Light'), stringsAsFactors = F)

library(tidyverse)

data.frame(t(combn(unique(df$drink_freq), 2)), stringsAsFactors = F) %>%
  mutate(counts = map2_dbl(X1, X2, ~length(intersect(df$ID[df$drink_freq==.x], 
                                                     df$ID[df$drink_freq==.y]))))

#                X1             X2 counts
# 1    Coffee Light    Water Heavy 1
# 2    Coffee Light     Tea Medium 1
# 3    Coffee Light  Coffee Medium 0
# 4    Coffee Light    Water Light 0
# 5    Coffee Light Espresso Light 0
# 6    Coffee Light     Soda Light 0
# 7    Coffee Light   Coffee Heavy 0
# 8     Water Heavy     Tea Medium 1
# 9     Water Heavy  Coffee Medium 0
# 10    Water Heavy    Water Light 0
# 11    Water Heavy Espresso Light 0
# 12    Water Heavy     Soda Light 0
# 13    Water Heavy   Coffee Heavy 0
# 14     Tea Medium  Coffee Medium 1
# 15     Tea Medium    Water Light 1
# 16     Tea Medium Espresso Light 1
# 17     Tea Medium     Soda Light 1
# 18     Tea Medium   Coffee Heavy 0
# 19  Coffee Medium    Water Light 2
# 20  Coffee Medium Espresso Light 1
# 21  Coffee Medium     Soda Light 2
# 22  Coffee Medium   Coffee Heavy 0
# 23    Water Light Espresso Light 1
# 24    Water Light     Soda Light 1
# 25    Water Light   Coffee Heavy 0
# 26 Espresso Light     Soda Light 1
# 27 Espresso Light   Coffee Heavy 0
# 28     Soda Light   Coffee Heavy 0

然后您可以将上述输出重塑为列联表。

注意,如果你想重塑并获得对称输出,你必须修改上面的代码以忽略饮料的顺序,通过创建所有可能的组合,如下所示:

expand.grid(X1=unique(df$drink_freq),
            X2=unique(df$drink_freq), stringsAsFactors = F) %>%
  mutate(counts = map2_dbl(X1, X2, ~length(intersect(df$ID[df$drink_freq==.x], 
                                                     df$ID[df$drink_freq==.y])))) %>% 
  filter(X1 != X2) 

【讨论】:

  • 太棒了,这正是我想要的!我在想我可能需要使用与长度相交,但使用 map2 函数是缺失的部分。谢谢!
  • 我有一个关于输出的快速问题。如果我只是简单地传播它,通过添加 %>% spread(X2, counts) 会有 NA 以组合形式出现在有数据的地方。例如,Tea Medium-Coffee Medium 有一个 1,当 Tea Medium 在垂直轴上而不是在水平轴上时显示。有没有办法解决这个问题?因为看看百分比分割也很好。再次感谢迄今为止的所有帮助!
  • 这是因为对于上述过程,饮料的顺序很重要。您没有在问题中指定它,但看起来您需要一个对称数据框作为输出,对吧?如果是这种情况,则需要更改流程。
  • 哦,好的,是的,顺序是完全任意的,所以我认为类似于相关矩阵的对称输出就足够了。然后我可以在事后附加行/列总计和其他简单的东西。但本质上,如果我将您的解决方案存储为 sol,然后创建一个新的 df,sol2 = sol,然后重命名列 names(sol2)[1:2] = c('X2', 'X1') 并将其附加到sol df, sol = rbind.data.frame(sol, sol2) 然后传播它你基本上得到对称输出。虽然我确信有更简单的方法
猜你喜欢
  • 2015-05-30
  • 2014-09-14
  • 2021-09-11
  • 1970-01-01
  • 2018-08-18
  • 1970-01-01
  • 2017-05-10
  • 1970-01-01
  • 2017-09-04
相关资源
最近更新 更多