R:在层次结构中分组
R: Grouping in a hierarchy
我正在处理一个带有六位数分组系统的数据集。前两位表示顶层分组,后两位表示不同的子组,最后两位表示子组内的具体类型。我想将数据分组到层次结构的顶层(仅前两位数字),并计算每组中的唯一名称。
GroupID 010203 的示例:
- 01表示宝马
- 02 表示 3 系列
- 03 表示 320i(确切型号)
在这个例子中我只关心每个品牌有多少。
玩具数据集和想要的输出:
df <- data.table(Quarter = c('Q4', 'Q4', 'Q4', 'Q4', 'Q3'),
GroupID = c(010203, 150503, 010101, 150609, 010000),
Name = c('AAAA', 'AAAA', 'BBBB', 'BBBB', 'CCCC'))
输出:
Quarter Group Counts
Q3 01 1
Q4 01 2
Q4 15 2
使用data.table
我们可以做到:
library(data.table)
dt[, Group := substr(GroupID, 1, 2)][
, Counts := .N, by = list(Group, Quarter)][
, head(.SD, 1), by = .(Quarter, Group, Counts)][
, .(Quarter, Group, Counts)]
Returns:
Quarter Group Counts
1: Q4 01 2
2: Q4 15 2
3: Q3 01 1
使用 dplyr
和 stringr
我们可以做类似的事情:
library(dplyr)
library(stringr)
df %>%
mutate(Group = str_sub(GroupID, 1, 2)) %>%
group_by(Group, Quarter) %>%
summarise(Counts = n()) %>%
ungroup()
Returns:
# A tibble: 3 x 3
Group Quarter Counts
<chr> <fct> <int>
1 01 Q3 1
2 01 Q4 2
3 15 Q4 2
由于您已经在使用 data.table
,您可以:
df[, Group := substr(GroupID,1,2)]
df <- df[,Counts := .N, .(Group,Quarter)][,.(Group, Quarter, Counts)]
df <- unique(df)
print(df)
Group Quarter Counts
1: 10 Q4 2
2: 15 Q4 2
3: 10 Q3 1
这是我使用 plyr
和 base R
的简单解决方案,速度很快。
library(plyr)
df$breakid <- as.character((substr(df$GroupID, start =0 , stop = 2)))
d <- plyr::count(df, c("Quarter", "breakid"))
结果
Quarter breakid freq
Q3 01 1
Q4 01 2
Q4 15 2
或者,使用 tapply
(和 data.table
索引):
df$Brand <- substr(df$GroupID, 1, 2)
tapply(df$Brand, df[, .(Quarter, Brand)], length)
(如果你不关心输出是一个矩阵)。
我正在处理一个带有六位数分组系统的数据集。前两位表示顶层分组,后两位表示不同的子组,最后两位表示子组内的具体类型。我想将数据分组到层次结构的顶层(仅前两位数字),并计算每组中的唯一名称。
GroupID 010203 的示例:
- 01表示宝马
- 02 表示 3 系列
- 03 表示 320i(确切型号)
在这个例子中我只关心每个品牌有多少。
玩具数据集和想要的输出:
df <- data.table(Quarter = c('Q4', 'Q4', 'Q4', 'Q4', 'Q3'),
GroupID = c(010203, 150503, 010101, 150609, 010000),
Name = c('AAAA', 'AAAA', 'BBBB', 'BBBB', 'CCCC'))
输出:
Quarter Group Counts
Q3 01 1
Q4 01 2
Q4 15 2
使用data.table
我们可以做到:
library(data.table)
dt[, Group := substr(GroupID, 1, 2)][
, Counts := .N, by = list(Group, Quarter)][
, head(.SD, 1), by = .(Quarter, Group, Counts)][
, .(Quarter, Group, Counts)]
Returns:
Quarter Group Counts 1: Q4 01 2 2: Q4 15 2 3: Q3 01 1
使用 dplyr
和 stringr
我们可以做类似的事情:
library(dplyr)
library(stringr)
df %>%
mutate(Group = str_sub(GroupID, 1, 2)) %>%
group_by(Group, Quarter) %>%
summarise(Counts = n()) %>%
ungroup()
Returns:
# A tibble: 3 x 3 Group Quarter Counts <chr> <fct> <int> 1 01 Q3 1 2 01 Q4 2 3 15 Q4 2
由于您已经在使用 data.table
,您可以:
df[, Group := substr(GroupID,1,2)]
df <- df[,Counts := .N, .(Group,Quarter)][,.(Group, Quarter, Counts)]
df <- unique(df)
print(df)
Group Quarter Counts
1: 10 Q4 2
2: 15 Q4 2
3: 10 Q3 1
这是我使用 plyr
和 base R
的简单解决方案,速度很快。
library(plyr)
df$breakid <- as.character((substr(df$GroupID, start =0 , stop = 2)))
d <- plyr::count(df, c("Quarter", "breakid"))
结果
Quarter breakid freq
Q3 01 1
Q4 01 2
Q4 15 2
或者,使用 tapply
(和 data.table
索引):
df$Brand <- substr(df$GroupID, 1, 2)
tapply(df$Brand, df[, .(Quarter, Brand)], length)
(如果你不关心输出是一个矩阵)。