在 R Dplyr 中使用 group_by 函式
- 
          
            在 R 中設定 dplyr包
- 
          
            在 R 中使用 group_by()函式
- 
          
            在 R 中使用 group_by()和summarize()
- 
          
            在 R 中使用 group_by()和filter()
- 
          
            在 R 中使用 group_by()和mutate()
- 在 R 中取消組合 tibble
- 參考
 
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_one 和 Col_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()
與具有單獨的 where 和 having 子句的 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 的文件。
