Как я могу суммировать эти данные с R? - PullRequest
0 голосов
/ 05 марта 2019

Я анализирую поток покупателей между различными торговыми площадками.У меня есть такие данные:

df <- data.frame(customer.id=letters[seq(1,7)], 
                 shop.1=c(1,1,1,1,1,0,0),
                 shop.2=c(0,0,1,1,1,1,0),
                 shop.3=c(1,0,0,0,0,0,1))
df
#>   customer.id shop.1 shop.2 shop.3
#> 1           a      1      0      1
#> 2           b      1      0      0  
#> 3           c      1      1      0 
#> 4           d      1      1      0 
#> 5           e      1      1      0 
#> 6           f      0      1      0 
#> 7           g      0      0      1

Так, например:

  • покупатель "a" покупал только в магазинах 1 и 3,

  • покупатель "b" покупал только в магазине 1,

  • покупатель "c" покупал только в магазинах 1 и 2,

  • и т. Д.

Я хочу обобщить данные следующим образом:

#>           shop.1 shop.2 shop.3 
#> shop.1         5      3      1
#> shop.2         3      4      0       
#> shop.3         1      0      2       

Так, например, строка 1 гласит:

  • 5в магазине 1 и магазине 1 (очевидно, это избыточное наблюдение)
  • 3 человека в магазине 1 и магазине 2
  • 1 человек в магазине 1 и магазине 3

Как я могу это сделать (обратите внимание: в моем наборе данных много магазинов, поэтому предпочтителен масштабируемый подход)?

Ответы [ 3 ]

0 голосов
/ 05 марта 2019

crossprod может позаботиться о том, что вы хотите сделать, после нескольких основных манипуляций, чтобы получить его в 2 столбца, представляющих customer и shop соответственно:

tmp <- cbind(df[1],stack(df[-1]))
tmp <- tmp[tmp$values==1,]

crossprod(table(tmp[c(1,3)]))

#        ind
#ind      shop.1 shop.2 shop.3
#  shop.1      5      3      1
#  shop.2      3      4      0
#  shop.3      1      0      2
0 голосов
/ 05 марта 2019

Фактически, матричной операции кажется достаточно, потому что фрейм данных имеет только 0 и 1.

Сначала, исключите столбец customer.id и измените data.frame на matrix.Это может быть легко.(mydf - это имя вашего фрейма данных.)

# base R way
as.matrix(mydf[,-1])
#>      shop.1 shop.2 shop.3
#> [1,]      1      0      1
#> [2,]      1      0      0
#> [3,]      1      1      0
#> [4,]      1      1      0
#> [5,]      1      1      0
#> [6,]      0      1      0
#> [7,]      0      0      1

library(dplyr) #dplyr way
(mymat <-
  mydf %>% 
  select(-customer.id) %>% 
  as.matrix())
#>      shop.1 shop.2 shop.3
#> [1,]      1      0      1
#> [2,]      1      0      0
#> [3,]      1      1      0
#> [4,]      1      1      0
#> [5,]      1      1      0
#> [6,]      0      1      0
#> [7,]      0      0      1

С этой матрицей просто выполните матричную операцию , как показано ниже.

t(mymat) %*% mymat
#>        shop.1 shop.2 shop.3
#> shop.1      5      3      1
#> shop.2      3      4      0
#> shop.3      1      0      2

Вымогу получить ваш ответ.

0 голосов
/ 05 марта 2019

Вы хотите составить таблицу совместного вхождения из shop.* переменных:

df[,2:4] <- sapply(df[,2:4], function(x) { ifelse(x=="", 0, 1) } )

1) Предположительно, это можно сделать с помощью ftable(xtabs(...)), но я боролся с этим длявозраст и не мог получить это.Самое близкое, что я получил, это:

> ftable(xtabs(~ shop.1 + shop.2 + shop.3, df))

              shop.3 0 1
shop.1 shop.2           
0      0             0 1
       1             1 0
1      0             1 1
       1             3 0

2) Как показало @thelatemail, вы также можете:

# Transform your df from wide-form to long-form...
library(dplyr)
library(reshape2)
occurrence_df <- reshape2::melt(df, id.vars='customer.id') %>%
                 dplyr::filter(value==1)

   customer.id variable value
1            a   shop.1     1
2            b   shop.1     1
3            c   shop.1     1
4            d   shop.1     1
5            e   shop.1     1
6            c   shop.2     1
7            d   shop.2     1
8            e   shop.2     1
9            f   shop.2     1
10           a   shop.3     1
11           g   shop.3     1

На самом деле мы можем удалить столбец value после фильтра, чтобы мы моглиpipe %>% select(-value)

   customer.id variable
1            a   shop.1
2            b   shop.1
3            c   shop.1
4            d   shop.1
5            e   shop.1
6            c   shop.2
7            d   shop.2
8            e   shop.2
9            f   shop.2
10           a   shop.3
11           g   shop.3

# затем тот же шаг кросс-процесса, что и ответ @ thelatemail:

crossprod(table(occurrence_df))

        variable
variable shop.1 shop.2 shop.3
  shop.1      5      3      1
  shop.2      3      4      0
  shop.3      1      0      2

(Сноски:

  • Сначала ваши данные должны быть числовыми(или фактор), а не строка. Вы хотите преобразовать "x" в 1 и "" в 0.
  • Если они являются строками, потому что они пришли из read.csv, используйте read.csv arguments stringsAsFactors=TRUE длясделайте их множителями, или colClasses, чтобы сделать их числовыми, и посмотрите все эти дублирующие вопросы.)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...