一意の組み合わせとその頻度を生成するためのソリューションはRにありますか?

Dec 09 2020

これが私のコードです。Food列の繰り返しではないすべての組み合わせと、ID列に表示される回数を生成しようとしています。


customerDataFrame <- data.frame(CustomerID = c('A', 'B', 'B', 'C', 'D', 'D'),
                                Food = c('Pizza', 'Pizza', 'Tacos', 'Tacos', 'Tacos', 'Pizza'))

customerDataFrame %>% 
  group_by(CustomerID) %>% 
  summarise_all(funs(toString(unique(.)))) %>%
  ungroup() %>%
  group_by(Food) %>%
  summarise(n= n())

現在の出力は次のとおりです。

# A tibble: 4 x 2
  Food             n
  <chr>        <int>
1 Pizza            1
2 Pizza, Tacos     1
3 Tacos            1
4 Tacos, Pizza     1

(Pizza、Tacos)と(Tacos、Pizza)を購入する顧客は同じグループに属している必要があるため、これは技術的に正しくありません。彼らがどの注文で購入するかは問題ではありません。

(私はこの回答からコードを取得しました:dplyrを使用して、特定のグループの値の一意の組み合わせのベクトルを作成します)

これが私が取得しようとしているものです:

# A tibble: 4 x 2
  Food             n
  <chr>        <int>
1 Pizza            1
2 Pizza, Tacos     2
3 Tacos            1

回答

3 Duck Dec 09 2020 at 21:15

これを試して。summarise()期待される結果を得るために2倍にすることができます:

library(dplyr)
#Code
new <- customerDataFrame %>%
  arrange(CustomerID,Food)%>%
  group_by(CustomerID) %>%
  summarise(Food=paste0(Food,collapse = ',')) %>%
  group_by(Food,.drop = T) %>%
  summarise(N=n())

出力:

# A tibble: 3 x 2
  Food            N
  <chr>       <int>
1 Pizza           1
2 Pizza,Tacos     2
3 Tacos           1

同じ出力は、以下を使用して到達できますtoString()

#Code 2
new <- customerDataFrame %>%
  arrange(CustomerID,Food)%>%
  group_by(CustomerID) %>%
  summarise(Food=toString(Food)) %>%
  group_by(Food,.drop = T) %>%
  summarise(N=n())
3 RonakShah Dec 09 2020 at 21:25

を使用toString sortして折りたたむ場合Food

library(dplyr)

customerDataFrame %>% 
  group_by(CustomerID) %>% 
  summarise(Food = toString(sort(Food))) %>%
  count(Food)

#   Food            n
#  <chr>        <int>
#1 Pizza            1
#2 Pizza, Tacos     2
#3 Tacos            1
akrun Dec 10 2020 at 03:33

ではbase R、私たちは使用することができtableaggregate

table(aggregate(Food ~ CustomerID, 
   customerDataFrame[do.call(order, customerDataFrame),], FUN = toString)$Food)

#  Pizza Pizza, Tacos        Tacos 
#      1            2            1