根据公共元素的数量对数据帧进行分组

时间:2018-03-05 11:42:37

标签: r dataframe

我有一个具有以下结构的数据框(df):

Store Item
S1    I1
S1    I2
S1    I3
S1    I4
S2    I1
S2    I2
S2    I3
S3    I1
S3    I2
S3    I3
S4    I5

我希望有一种方法可以根据商店中的常见元素获取商店的组/集群,具体如下:

Store Group Common_element_with_group
S1    1     I1,I2,I3,I4
S2    2     I1,I2,I3
S3    2     I1,I2,I3
S4    3     I5

有没有人知道实现这一目标的方法,我甚至不采用这种方法。

4 个答案:

答案 0 :(得分:3)

以下是来自aggregate

base R选项
transform(aggregate(.~Store, df, toString), Group = cumsum(!duplicated(Item)))
#  Store           Item Group
#1    S1 I1, I2, I3, I4     1
#2    S2     I1, I2, I3     2
#3    S3     I1, I2, I3     2
#4    S4             I5     3

或者可以使用data.table

完成此操作
library(data.table)
setDT(df)[, .(Item = toString(Item)), Store][, Group := cumsum(!duplicated(Item))][]

答案 1 :(得分:1)

你可以在基础R中做这样的事情:

df <- stack(lapply(split(df, df$Store), function(x) paste0(x$Item, collapse = ",")));
df$Group <- as.numeric(factor(df$values, levels = unique(df$values)));
df;
#       values ind Group
#1 I1,I2,I3,I4  S1     1
#2    I1,I2,I3  S2     2
#3    I1,I2,I3  S3     2
#4          I5  S4     3
df <- read.table(text =
    "Store Item
S1    I1
S1    I2
S1    I3
S1    I4
S2    I1
S2    I2
S2    I3
S3    I1
S3    I2
S3    I3
S4    I5", header = T)

答案 2 :(得分:1)

您可以尝试:

library(tidyverse)
d %>% 
  group_by(Store) %>% 
  summarise(Common_element_with_group=paste(Item, collapse=","),
            Group=factor(n())) %>% 
  mutate(Group=factor(Group, levels = levels(Group), labels = 1:nlevels(Group)))
# A tibble: 4 x 3
   Store Common_element_with_group  Group
  <fctr>                     <chr> <fctr>
1     S1               I1,I2,I3,I4      1
2     S2                  I1,I2,I3      2
3     S3                  I1,I2,I3      2
4     S4                        I5      3

数据:

d <- read.table(text="Store Item
S1    I1
                S1    I2
                S1    I3
                S1    I4
                S2    I1
                S2    I2
                S2    I3
                S3    I1
                S3    I2
                S3    I3
                S4    I5", header=T)

答案 3 :(得分:1)

使用aggregate的解决方案。

agg <- aggregate(Item ~ Store, df, paste, collapse = ", ")

然后,您可以使用

创建列Group
agg$Group <- seq_len(nrow(agg))

最后,更改列顺序:

agg <- agg[, c(1, 3, 2)]
agg
#  Store Group           Item
#1    S1     1 I1, I2, I3, I4
#2    S2     2     I1, I2, I3
#3    S3     3     I1, I2, I3
#4    S4     4             I5