使用多列创建数据透视表 table 并按唯一出现次数进行聚合
Making Pivot table with Multiple Columns and Aggregating by Unique Occurences
我很难思考这个问题或在网上找到指南。
我有会员数据。我想看看有多少会员在取消会员资格之前在特定月份坚持了下来。我可以看到他们加入的月份,我可以通过查看他们的交易号(每月增加 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 或类似的包吗?希望我没有破坏解释或格式,请随时提出任何问题。
谢谢!
下面是一个使用 tidyverse 函数 dplyr::n_distinct
和 tidyr::spread
的可重现示例。
我首先将您的数据表示为小标题(或者您也可以同样使用数据框)。
接下来我们按 Transactionno
和 JoinedMonth
分组,然后再计算不同的名称。要以 table 格式获取它,您要求我们使用 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) 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) table 另一种基础 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])
我很难思考这个问题或在网上找到指南。
我有会员数据。我想看看有多少会员在取消会员资格之前在特定月份坚持了下来。我可以看到他们加入的月份,我可以通过查看他们的交易号(每月增加 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 或类似的包吗?希望我没有破坏解释或格式,请随时提出任何问题。
谢谢!
下面是一个使用 tidyverse 函数 dplyr::n_distinct
和 tidyr::spread
的可重现示例。
我首先将您的数据表示为小标题(或者您也可以同样使用数据框)。
接下来我们按 Transactionno
和 JoinedMonth
分组,然后再计算不同的名称。要以 table 格式获取它,您要求我们使用 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) 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) table 另一种基础 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])