R - 跨列的不同计数
R - Distinct count across columns
我有一个庞大而复杂的数据集(有点太复杂了,不能在这里分享,而且可能没有必要分享整个数据集)但这里有一个它看起来像的例子。这只是一天,完整样本跨越数百天:
我想做的是设计一种方法来计算每个 Row
中 Genre
的变化。更简单地说(我希望):每个 Row
有 12 个 Column
,我想测量 Genre
在这 12 个 Column
中的变化(这是 BBC iPlayer,你们中的许多人可能都很熟悉)。例如。如果 Row
由 4 个“体育”、4 个“剧情”和 4 个“纪录片”组成,则将有 3 个流派的不同计数。
我认为简单的不同计数是衡量每一行内变化的好方法(计数越不同,变化越大),但这不是一种非常微妙的方法。 IE。如果一行由 11 个“运动”和 1 个“纪录片”组成,则不同的计数为 2。如果它由 6 个“运动”和 6 个“纪录片”组成,它仍然是不同的计数 2 - 所以不同的计数并不是真的在这个意义上帮助。
我想我在这里就两件事征求意见:
- 首先,衡量变异的最合适方法是什么
每个
Row
中的 Genre
- 其次,我将如何去做呢! IE。我需要什么代码/包?
我希望一切都清楚,但如果没有,我很乐意详细说明任何事情。也许值得注意(正如我上面提到的)我想确定特定日期的变化,这里共享的示例数据只是一个日期(但我有数百个)。
提前致谢:)
*** 更新 ***
感谢您的评论 - 特别是关于分享真实数据的快照(您将在下面找到)。抱歉 - 我在这方面有点新手,不太熟悉正确的约定!
这是一个数据样本 - 我希望它是正确的,我希望它能有所帮助:
structure(list(Row = c(0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L,
3L, 3L, 3L, 3L), Genre = c("", "Sport", "Drama", "Documentary",
"Entertainment", "Drama", "Comedy", "Crime Drama", "Entertainment",
"Documentary", "Entertainment", "History", "Crime Drama", "",
"", "", "", "", "", "", "", "", "", "", "", "Drama", "Drama",
"Documentary", "Entertainment", "Period Drama"), Column = c(1L,
1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 1L, 2L, 3L,
4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 1L, 2L, 3L, 4L, 5L)), row.names = c(NA,
30L), class = "data.frame")
首先创建一些可重现的数据。我们只需要 Row
和 Genre
:
set.seed(42)
Row <- rep(1:10, each=10)
Genre <- sample(c("Sport", "Drama", "Documentary", "Entertainment", "History", "Crime Drama", "Period Drama", "Film - Comedy", "Film-Thriller"), 100, replace=TRUE)
example <- data.frame(Row, Genre)
str(example)
# 'data.frame': 100 obs. of 2 variables:
# $ Row : int 1 1 1 1 1 1 1 1 1 1 ...
# $ Genre: chr "Sport" "History" "Sport" "Film-Thriller" ...
现在获取每一行中不同流派的数量:
Count <- tapply(example$Genre, example$Row, function(x) length(unique(x)))
Count
# 1 2 3 4 5 6 7 8 9 10
# 7 5 6 7 6 8 7 7 7 6
第 1 行有 7 个类型,第 2 行只有 5 个类型。更多详情:
xtabs(~Genre+Row, example)
# Row
# Genre 1 2 3 4 5 6 7 8 9 10
# Crime Drama 0 0 1 1 3 1 1 0 2 1
# Documentary 0 1 1 1 1 0 1 0 1 0
# Drama 1 1 1 3 2 1 2 1 1 0
# Entertainment 2 2 3 1 1 1 1 2 0 0
# Film - Comedy 1 0 3 2 0 1 2 2 0 2
# Film-Thriller 1 3 0 0 0 1 1 1 2 2
# History 1 3 0 1 2 1 2 2 2 1
# Period Drama 1 0 0 1 0 2 0 1 1 2
# Sport 3 0 1 0 1 2 0 1 1 2
可重现的样本数据:
set.seed(42)
sampdata <- transform(
expand.grid(Date = Sys.Date() + 0:2, Row=0:3, Column=1:12),
Genre = sample(c("Crime Drama","Documentary","Drama","Entertainment"),
size = 48, replace = TRUE)
)
head(sampdata)
# Date Row Column Genre
# 1 2022-02-18 0 1 Crime Drama
# 2 2022-02-19 0 1 Crime Drama
# 3 2022-02-20 0 1 Crime Drama
# 4 2022-02-18 1 1 Crime Drama
# 5 2022-02-19 1 1 Documentary
# 6 2022-02-20 1 1 Entertainment
nrow(sampdata)
# [1] 144
使用dplyr
和tidyr
,我们可以分组,汇总,然后进行透视:
library(dplyr)
# library(tidyr) # pivot_wider
sampdata %>%
group_by(Date, Row) %>%
summarize(
Uniq = n_distinct(Genre),
Var = var(table(Genre))
) %>%
tidyr::pivot_wider(
Date, names_from = Row, values_from = c(Uniq, Var)
) %>%
ungroup()
# # A tibble: 3 x 9
# Date Uniq_0 Uniq_1 Uniq_2 Uniq_3 Var_0 Var_1 Var_2 Var_3
# <date> <int> <int> <int> <int> <dbl> <dbl> <dbl> <dbl>
# 1 2022-02-18 2 3 2 2 0 3 18 18
# 2 2022-02-19 3 3 1 3 3 3 NA 3
# 3 2022-02-20 2 3 3 3 18 3 3 3
两件事:Uniq_#
是每个 Row
不同 Genre
值的计数,Var_#
是 方差 的计数。例如,在您的示例中,计数为 6 和 6 的两个类型的方差为 0
,但计数为 11 和 1 的方差为 50 (var(c(11,1))
),表明该类型的变化更大Date
/Row
组合。
因为我们用的是group_by
,如果你的分组变量再多一些,那就是straight-forward来扩展这个,无论是在分组上还是在聚合上除了[=24我们还能做什么=] 和 var(.)
.
顺便说一句:根据您的其他计算、分析和 reporting/plotting,将其保留为 long 格式可能会有用,删除 pivot_wider
.
sampdata %>%
group_by(Date, Row) %>%
summarize(
Uniq = n_distinct(Genre),
Var = var(table(Genre))
) %>%
ungroup()
# # A tibble: 12 x 4
# Date Row Uniq Var
# <date> <int> <int> <dbl>
# 1 2022-02-18 0 2 0
# 2 2022-02-18 1 3 3
# 3 2022-02-18 2 2 18
# 4 2022-02-18 3 2 18
# 5 2022-02-19 0 3 3
# 6 2022-02-19 1 3 3
# 7 2022-02-19 2 1 NA
# 8 2022-02-19 3 3 3
# 9 2022-02-20 0 2 18
# 10 2022-02-20 1 3 3
# 11 2022-02-20 2 3 3
# 12 2022-02-20 3 3 3
何时保持它的好例子包括 Date
/Row
的进一步聚合和 ggplot2
的绘图(这确实奖励 long-data)。
我有一个庞大而复杂的数据集(有点太复杂了,不能在这里分享,而且可能没有必要分享整个数据集)但这里有一个它看起来像的例子。这只是一天,完整样本跨越数百天:
我想做的是设计一种方法来计算每个 Row
中 Genre
的变化。更简单地说(我希望):每个 Row
有 12 个 Column
,我想测量 Genre
在这 12 个 Column
中的变化(这是 BBC iPlayer,你们中的许多人可能都很熟悉)。例如。如果 Row
由 4 个“体育”、4 个“剧情”和 4 个“纪录片”组成,则将有 3 个流派的不同计数。
我认为简单的不同计数是衡量每一行内变化的好方法(计数越不同,变化越大),但这不是一种非常微妙的方法。 IE。如果一行由 11 个“运动”和 1 个“纪录片”组成,则不同的计数为 2。如果它由 6 个“运动”和 6 个“纪录片”组成,它仍然是不同的计数 2 - 所以不同的计数并不是真的在这个意义上帮助。
我想我在这里就两件事征求意见:
- 首先,衡量变异的最合适方法是什么
每个
Row
中的 - 其次,我将如何去做呢! IE。我需要什么代码/包?
Genre
我希望一切都清楚,但如果没有,我很乐意详细说明任何事情。也许值得注意(正如我上面提到的)我想确定特定日期的变化,这里共享的示例数据只是一个日期(但我有数百个)。
提前致谢:)
*** 更新 ***
感谢您的评论 - 特别是关于分享真实数据的快照(您将在下面找到)。抱歉 - 我在这方面有点新手,不太熟悉正确的约定!
这是一个数据样本 - 我希望它是正确的,我希望它能有所帮助:
structure(list(Row = c(0L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L,
3L, 3L, 3L, 3L), Genre = c("", "Sport", "Drama", "Documentary",
"Entertainment", "Drama", "Comedy", "Crime Drama", "Entertainment",
"Documentary", "Entertainment", "History", "Crime Drama", "",
"", "", "", "", "", "", "", "", "", "", "", "Drama", "Drama",
"Documentary", "Entertainment", "Period Drama"), Column = c(1L,
1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 1L, 2L, 3L,
4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 1L, 2L, 3L, 4L, 5L)), row.names = c(NA,
30L), class = "data.frame")
首先创建一些可重现的数据。我们只需要 Row
和 Genre
:
set.seed(42)
Row <- rep(1:10, each=10)
Genre <- sample(c("Sport", "Drama", "Documentary", "Entertainment", "History", "Crime Drama", "Period Drama", "Film - Comedy", "Film-Thriller"), 100, replace=TRUE)
example <- data.frame(Row, Genre)
str(example)
# 'data.frame': 100 obs. of 2 variables:
# $ Row : int 1 1 1 1 1 1 1 1 1 1 ...
# $ Genre: chr "Sport" "History" "Sport" "Film-Thriller" ...
现在获取每一行中不同流派的数量:
Count <- tapply(example$Genre, example$Row, function(x) length(unique(x)))
Count
# 1 2 3 4 5 6 7 8 9 10
# 7 5 6 7 6 8 7 7 7 6
第 1 行有 7 个类型,第 2 行只有 5 个类型。更多详情:
xtabs(~Genre+Row, example)
# Row
# Genre 1 2 3 4 5 6 7 8 9 10
# Crime Drama 0 0 1 1 3 1 1 0 2 1
# Documentary 0 1 1 1 1 0 1 0 1 0
# Drama 1 1 1 3 2 1 2 1 1 0
# Entertainment 2 2 3 1 1 1 1 2 0 0
# Film - Comedy 1 0 3 2 0 1 2 2 0 2
# Film-Thriller 1 3 0 0 0 1 1 1 2 2
# History 1 3 0 1 2 1 2 2 2 1
# Period Drama 1 0 0 1 0 2 0 1 1 2
# Sport 3 0 1 0 1 2 0 1 1 2
可重现的样本数据:
set.seed(42)
sampdata <- transform(
expand.grid(Date = Sys.Date() + 0:2, Row=0:3, Column=1:12),
Genre = sample(c("Crime Drama","Documentary","Drama","Entertainment"),
size = 48, replace = TRUE)
)
head(sampdata)
# Date Row Column Genre
# 1 2022-02-18 0 1 Crime Drama
# 2 2022-02-19 0 1 Crime Drama
# 3 2022-02-20 0 1 Crime Drama
# 4 2022-02-18 1 1 Crime Drama
# 5 2022-02-19 1 1 Documentary
# 6 2022-02-20 1 1 Entertainment
nrow(sampdata)
# [1] 144
使用dplyr
和tidyr
,我们可以分组,汇总,然后进行透视:
library(dplyr)
# library(tidyr) # pivot_wider
sampdata %>%
group_by(Date, Row) %>%
summarize(
Uniq = n_distinct(Genre),
Var = var(table(Genre))
) %>%
tidyr::pivot_wider(
Date, names_from = Row, values_from = c(Uniq, Var)
) %>%
ungroup()
# # A tibble: 3 x 9
# Date Uniq_0 Uniq_1 Uniq_2 Uniq_3 Var_0 Var_1 Var_2 Var_3
# <date> <int> <int> <int> <int> <dbl> <dbl> <dbl> <dbl>
# 1 2022-02-18 2 3 2 2 0 3 18 18
# 2 2022-02-19 3 3 1 3 3 3 NA 3
# 3 2022-02-20 2 3 3 3 18 3 3 3
两件事:Uniq_#
是每个 Row
不同 Genre
值的计数,Var_#
是 方差 的计数。例如,在您的示例中,计数为 6 和 6 的两个类型的方差为 0
,但计数为 11 和 1 的方差为 50 (var(c(11,1))
),表明该类型的变化更大Date
/Row
组合。
因为我们用的是group_by
,如果你的分组变量再多一些,那就是straight-forward来扩展这个,无论是在分组上还是在聚合上除了[=24我们还能做什么=] 和 var(.)
.
顺便说一句:根据您的其他计算、分析和 reporting/plotting,将其保留为 long 格式可能会有用,删除 pivot_wider
.
sampdata %>%
group_by(Date, Row) %>%
summarize(
Uniq = n_distinct(Genre),
Var = var(table(Genre))
) %>%
ungroup()
# # A tibble: 12 x 4
# Date Row Uniq Var
# <date> <int> <int> <dbl>
# 1 2022-02-18 0 2 0
# 2 2022-02-18 1 3 3
# 3 2022-02-18 2 2 18
# 4 2022-02-18 3 2 18
# 5 2022-02-19 0 3 3
# 6 2022-02-19 1 3 3
# 7 2022-02-19 2 1 NA
# 8 2022-02-19 3 3 3
# 9 2022-02-20 0 2 18
# 10 2022-02-20 1 3 3
# 11 2022-02-20 2 3 3
# 12 2022-02-20 3 3 3
何时保持它的好例子包括 Date
/Row
的进一步聚合和 ggplot2
的绘图(这确实奖励 long-data)。