Создание сводной таблицы с несколькими столбцами и агрегирование по уникальным вхождениям - PullRequest
0 голосов
/ 31 августа 2018

Мне трудно обдумать это или найти руководство в Интернете.

У меня есть данные о членстве. Я хочу узнать, сколько членов продлится в конкретном месяце, прежде чем отказаться от членства. Я вижу, к какому месяцу они присоединились, и могу видеть, как долго они были активны, посмотрев на их транзакцию № (она увеличивается на 1 каждый месяц). Поэтому, если я отслеживаю транзакции «Нет» для каждого месяца, я могу получить информацию о том, сколько людей присоединилось в этом месяце и каково было снижение.

Важно отметить, что иногда один и тот же участник совершает несколько транзакций в течение месяца, но я хотел бы посчитать этого участника только один раз, поэтому мне нужно будет подсчитать этого участника только один раз.

Name | Joined Month | Transaction no
Adam | Jan          | 1
Adam | Jan          | 2
Adam | Jan          | 2
Ben  | Jan          | 1
Ben  | Jan          | 2
Ben  | Jan          | 3
Ben  | Jan          | 4
Cathy| Jan          | 1
Donna| Feb          | 1
Donna| Feb          | 2
Donna| Feb          | 3
Evan | Mar          | 1
Evan | Mar          | 1
Frank | Mar         | 1
Frank | Mar         | 2

Агрегирование для отдельных членов с месяцами в виде столбцов, результат будет выглядеть примерно так:

Transaction# | Jan | Feb | March
1            | 3   | 1   | 2 
2            | 2   | 1   | 1
3            | 1   | 1   | 0
4            | 1   | 0   | 0

Любые советы или указатели в правильном направлении были бы очень полезны. Должен ли я использовать Reshape2 или аналогичный пакет? Надеюсь, я не вырезал объяснение или форматирование, пожалуйста, не стесняйтесь задавать любые вопросы.

Спасибо!

Ответы [ 2 ]

0 голосов
/ 31 августа 2018

1) xtabs В этом однострочнике используется база R и ввод DF, воспроизводимый в примечании ниже. Обратите внимание, что мы предполагаем, что Joined.Month - это фактор с уровнями Jan, Feb, Mar, чтобы гарантировать, что выходные данные будут отсортированы в этом порядке (а не по алфавиту).

xtabs(~ Transaction.no + Joined.Month, unique(DF))

дает:

              Joined.Month
Transaction.no Jan Feb Mar
             1   1   3   2
             2   1   2   1
             3   1   1   0
             4   0   1   0

2) таблица Еще один базовый подход R.

with(unique(DF), table(Transaction.no, Joined.Month))

дает:

              Joined.Month
Transaction.no Jan Feb Mar
             1   3   1   2
             2   2   1   1
             3   1   1   0
             4   1   0   0

2a) Это также сработает и будет короче, но не совсем так:

table(unique(DF)[3:2])

3) tapply При этом также используется только базовая R:

u <- unique(DF)
tapply(u[[1]], u[3:2], length, default = 0)

дает:

              Joined.Month
Transaction.no Jan Feb Mar
             1   3   1   2
             2   2   1   1
             3   1   1   0
             4   1   0   0

Примечание

DF в воспроизводимой форме предполагается равным:

Lines <- "Name | Joined Month | Transaction no
Adam | Jan          | 1
Adam | Jan          | 2
Adam | Jan          | 2
Ben  | Jan          | 1
Ben  | Jan          | 2
Ben  | Jan          | 3
Ben  | Jan          | 4
Cathy| Jan          | 1
Donna| Feb          | 1
Donna| Feb          | 2
Donna| Feb          | 3
Evan | Mar          | 1
Evan | Mar          | 1
Frank | Mar         | 1
Frank | Mar         | 2"

DF <- read.table(text = Lines, header = TRUE, sep = "|", 
  strip.white = TRUE, as.is = TRUE)
DF$Joined.Month <- factor(DF$Joined.Month, lev = month.abb[1:3])
0 голосов
/ 31 августа 2018

Ниже приведен воспроизводимый пример, который использует функции обратного хода dplyr::n_distinct и tidyr::spread.

Сначала я представил ваши данные в виде таблицы (или вы могли бы одинаково хорошо использовать фрейм данных).

Затем мы группируем по Transactionno и JoinedMonth перед подсчетом различных Имен. Чтобы получить его в формате таблицы, которую вы запрашиваете, мы используем tidyr::spread. Если вы хотите, чтобы результирующие столбцы располагались в месячном порядке, важно, чтобы в вашем фрейме данных они были в качестве упорядоченных факторов.

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(tibble)
library(tidyr)

x <- tribble(
        ~Name , ~JoinedMonth,  ~Transactionno,
        "Adam" , "Jan"         , 1,
        "Adam" , "Jan"          , 2,
        "Adam" , "Jan"          , 2,
        "Ben"  , "Jan"          , 1,
        "Ben"  , "Jan"          , 2,
        "Ben"  , "Jan"          , 3,
        "Ben"  , "Jan"          , 4,
        "Cathy", "Jan"          , 1,
        "Donna", "Feb"          , 1,
        "Donna", "Feb"          , 2,
        "Donna", "Feb"          , 3,
        "Evan" , "Mar"          , 1,
        "Evan" , "Mar"          , 1,
        "Frank" , "Mar"         , 1,
        "Frank" , "Mar"         , 2  

)

x %>%
  group_by(Transactionno, JoinedMonth) %>% 
  summarise(ct = n_distinct(Name)) %>% 
  tidyr::spread(JoinedMonth, ct, fill = 0)
#> # A tibble: 4 x 4
#> # Groups:   Transactionno [4]
#>   Transactionno   Feb   Jan   Mar
#>           <dbl> <dbl> <dbl> <dbl>
#> 1            1.    1.    3.    2.
#> 2            2.    1.    2.    1.
#> 3            3.    1.    1.    0.
#> 4            4.    0.    1.    0.
...