制作具有多列的数据透视表并按唯一性进行汇总

时间:2018-08-30 21:41:51

标签: r dplyr pivot-table reshape2 distinct-values

我很难解决这个问题或在网上找到指南。

我有会员数据。我想看看在删除会员之前一个月有多少会员。通过查看交易编号,我可以看到他们加入的月份,也可以看到他们活跃了多长时间(每月增加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 :(得分:2)

以下是使用tidyverse函数dplyr::n_distincttidyr::spread的可复制示例。

我首先将您的数据表示为小标题(或者您可以同样好地使用数据框)。

接下来,我们将TransactionnoJoinedMonth分组,然后计算不同的名称。要以表格格式获取它,请使用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.

答案 1 :(得分:2)

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)轻按(这也仅使用基数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])