在 R Dplyr 中使用 group_by 函数

Jesse John 2023年1月30日
  1. 在 R 中设置 dplyr
  2. 在 R 中使用 group_by() 函数
  3. 在 R 中使用 group_by()summarize()
  4. 在 R 中使用 group_by()filter()
  5. 在 R 中使用 group_by()mutate()
  6. 在 R 中取消组合 tibble
  7. 参考
在 R Dplyr 中使用 group_by 函数

dplyr 包的 group_by() 函数帮助我们根据不同列中的值对行进行分组。然后,我们可以使用这些组来创建摘要、选择特定组进行进一步分析,或者根据组属性创建新列。

在 R 中设置 dplyr

我们需要安装和加载 dplyr 包并创建一个 tibble 来说明 group_by() 函数的工作。

示例代码:

# Install dplyr. Or install the tidyverse.
# UNCOMMENT THE FOLLOWING LINE TO INSTALL.
# install.packages("dplyr")

# Load dplyr
library(dplyr)

# Create vectors.
set.seed(11)
Col_code = sample(2200:7200, 10, replace=FALSE)
set.seed(222)
Col_one = sample(c("RD", "GN", "YW"), 10, replace = TRUE)
set.seed(4444)
Col_two = sample(c(3, 6), 10, replace = TRUE)

# Create a tibble.
my_t = tibble(Col_code, Col_one, Col_two)

# View the tibble.
my_t

在 R 中使用 group_by() 函数

当我们在 tibble 上使用 group_by() 时,似乎什么都没有发生。group_by() 函数仅标记用于分组的列。

示例代码:

# Use group_by().
group_by(my_t, Col_two)

输出:

# A tibble: 10 x 3
# Groups:   Col_two [2]
   Col_code Col_one Col_two
      <int> <chr>     <dbl>
 1     3985 RD            6
 2     2233 GN            6
 3     2895 YW            6
 4     3120 GN            6
 5     6439 YW            3
 6     4819 GN            6
 7     2573 GN            6
 8     5484 RD            6
 9     6509 GN            3
10     4309 RD            3

该代码返回一个与原始行数相同的 tibble。但请注意输出第二行中的注释。

指定的列已标记为分组。

在 R 中使用 group_by()summarize()

在许多情况下,group_by()summarize() 结合使用。该函数也可以拼写为 summarise()

由于我们已经对数据进行了分组,我们可以使用每个组的 summarize() 函数。在示例中,我们将使用 summarize() 中的 n() 函数来计算每个组中的行数。

我们还将使用管道运算符 %>% 来提高代码的可读性。

示例代码:

# Group by one column.
my_t %>% group_by(Col_two) %>% summarize(n())

输出:

# A tibble: 2 x 2
  Col_two `n()`
    <dbl> <int>
1       3     3
2       6     7

对于输出中的 Col_two 的每个值,我们都有一行。

我们可以一次按多列分组,如下所示。

示例代码:

# Group by more than one column.
my_t %>% group_by(Col_one, Col_two) %>% summarize(Num_Rows = n())

输出:

# A tibble: 6 x 3
# Groups:   Col_one [3]
  Col_one Col_two Num_Rows
  <chr>     <dbl>    <int>
1 GN            3        1
2 GN            6        4
3 RD            3        1
4 RD            6        2
5 YW            3        1
6 YW            6        1

在输出中,Col_oneCol_two 的每个组合都有一行,它们存在于原始 tibble 中。最后一列是用 n() 创建的,显示每个组合有多少行。

summarize() 函数可以计算多个组统计数据,例如 mean

示例代码:

# Calculate the mean.
# The output has 3 significant digits by default.
my_t %>% group_by(Col_one, Col_two) %>% summarize(mean(Col_code))

# Convert the output to a data frame to see the decimal places.
my_t %>% group_by(Col_one, Col_two) %>% summarize(mean(Col_code)) %>% as.data.frame()

输出:

> my_t %>% group_by(Col_one, Col_two) %>% summarize(mean(Col_code))
`summarise()` has grouped output by 'Col_one'. You can override using the `.groups` argument.
# A tibble: 6 x 3
# Groups:   Col_one [3]
  Col_one Col_two `mean(Col_code)`
  <chr>     <dbl>            <dbl>
1 GN            3            6509
2 GN            6            3186.
3 RD            3            4309
4 RD            6            4734.
5 YW            3            6439
6 YW            6            2895

> # Convert the output to a data frame to see the decimal places.
> my_t %>% group_by(Col_one, Col_two) %>% summarize(mean(Col_code)) %>% as.data.frame()
`summarise()` has grouped output by 'Col_one'. You can override using the `.groups` argument.
  Col_one Col_two mean(Col_code)
1      GN       3        6509.00
2      GN       6        3186.25
3      RD       3        4309.00
4      RD       6        4734.50
5      YW       3        6439.00
6      YW       6        2895.00

第一行返回了一个 tibble。默认情况下,tibble 打印具有三位有效数字的数字。

我们可以将输出转换为数据帧,以获得通常格式的输出。

我们还可以使用 tibble 包(或 pillar 包)的 num() 函数来显示十进制数字。我们将使用一个负整数来指定要显示的最大十进制位数。

示例代码:

library(tibble)
my_t %>% group_by(Col_one, Col_two) %>% summarize(tMean = num(mean(Col_code),digits=-2))

输出:

# A tibble: 6 x 3
# Groups:   Col_one [3]
  Col_one Col_two    tMean
  <chr>     <dbl> <num:.2>
1 GN            3  6509
2 GN            6  3186.25
3 RD            3  4309
4 RD            6  4734.5
5 YW            3  6439
6 YW            6  2895

需要特别注意的一点是 summarize() 删除了最后一个分组级别。为了看到这种效果,我们将中间结果保存到新对象中,并使用 group_vars() 函数来检查分组。

示例代码:

# Create a tibble with two levels of groupings.
tib_2_gr = my_t %>% group_by(Col_one, Col_two)

# Check that the tibble is grouped by two variables.
group_vars(tib_2_gr)

# Use the summarize() function once.
tib_1_gr = my_t %>% group_by(Col_one, Col_two) %>% summarize(Num_Rows = n())

# Check that the new tibble is grouped by only one variable after using summarize().
group_vars(tib_1_gr)

输出:

> group_vars(tib_2_gr)
[1] "Col_one" "Col_two"

> group_vars(tib_1_gr)
[1] "Col_one"

在 R 中使用 group_by()filter()

与具有单独的 wherehaving 子句的 SQL 不同,dplyr 的 filter() 函数适用于未分组和分组的数据。

我们将首先对分组 tibble 中原始数据的值使用 filter()

示例代码:

# Create a tibble with groups.
t_fil = my_t %>% group_by(Col_one, Col_two)

# Remove rows where Col_one is 'RD'.
t_fil %>% filter(Col_one != "RD")

输出:

# A tibble: 7 x 3
# Groups:   Col_one, Col_two [4]
  Col_code Col_one Col_two
     <int> <chr>     <dbl>
1     2233 GN            6
2     2895 YW            6
3     3120 GN            6
4     6439 YW            3
5     4819 GN            6
6     2573 GN            6
7     6509 GN            3

数据被过滤,分组仍然存在。我们现在可以使用 summarize() 来获取组摘要。

接下来,让我们对我们为组计算的值使用过滤器。

示例代码:

# First summarize.
t_fil %>% summarize(AVE = num(mean(Col_code), digits=-2))

# Now filter the summarized data.
# We will provide the new summary column to the filter function.
t_fil %>% summarize(AVE = num(mean(Col_code), digits=-2)) %>% filter(AVE > 4000)

输出:

# A tibble: 4 x 3
# Groups:   Col_one [3]
  Col_one Col_two      AVE
  <chr>     <dbl> <num:.2>
1 GN            3   6509
2 RD            3   4309
3 RD            6   4734.5
4 YW            3   6439

在 R 中使用 group_by()mutate()

在下面的示例中,我们将看到 mutate() 作用于已定义的组。新列给出了指定组 Col_one 的最小值 Col_code

示例代码:

# Group data.
t_mut = my_t %>% group_by(Col_one)

# Mutate based on grouping.
t_mut %>% mutate(MIN_GR_CODE = min(Col_code)) %>% arrange(.by_group = TRUE)

# If we use summarize(), we do not get the columns that were not grouped.
t_mut %>% summarize(MIN_GR_CODE = min(Col_code))

输出:

> # Mutate based on grouping.
> t_mut %>% mutate(MIN_GR_CODE = min(Col_code)) %>% arrange(.by_group = TRUE)
# A tibble: 10 x 4
# Groups:   Col_one [3]
   Col_code Col_one Col_two MIN_GR_CODE
      <int> <chr>     <dbl>       <int>
 1     2233 GN            6        2233
 2     3120 GN            6        2233
 3     4819 GN            6        2233
 4     2573 GN            6        2233
 5     6509 GN            3        2233
 6     3985 RD            6        3985
 7     5484 RD            6        3985
 8     4309 RD            3        3985
 9     2895 YW            6        2895
10     6439 YW            3        2895

> # If we use summarize(), we do not get the columns that were not grouped.
> t_mut %>% summarize(MIN_GR_CODE = min(Col_code))
# A tibble: 3 x 2
  Col_one MIN_GR_CODE
  <chr>         <int>
1 GN             2233
2 RD             3985
3 YW             2895

在 R 中取消组合 tibble

一旦我们完成了对使用 group_by() 分组的 tibble 的分析,我们应该使用 ungroup() 函数来删除分组。这将确保后续分析将在未分组的数据上进行。

我们需要将 tibble 的未分组版本保存为对象以使更改持久化。

示例代码:

# View a grouped tibble.
tib_2_gr
# The grouping is mentioned as the second line in the output.

# We can also check the grouping using the group_vars() function.
group_vars(tib_2_gr)

# ungroup() the tibble.
ungroup(tib_2_gr)

# Check the groups.
group_vars(tib_2_gr)
# The groups are still there because we did not save the change.

# Save to the same object name.
tib_2_gr = ungroup(tib_2_gr)

# Now check the groupings.
group_vars(tib_2_gr)
# There is no grouping.

最后两个命令的输出:

> # Save to the same object name.
> tib_2_gr = ungroup(tib_2_gr)
>
> # Now check the groupings.
> group_vars(tib_2_gr)
character(0)

参考

有关更多详细信息,请参阅 dplyr 的文档

对于 num(),请参阅 tibble 的文档

作者: Jesse John
Jesse John avatar Jesse John avatar

Jesse is passionate about data analysis and visualization. He uses the R statistical programming language for all aspects of his work.

相关文章 - R Function