用 3 个不同的分组变量在 R 中编写一个函数

Writing a function in R with 3 different grouping variables

我试图同时在三个不同的事物之后对 table 进行分组。我在最后一步有问题。 我的数据集 (band_list) 的前十行如下所示:

   BandName         Year BandType
  1 Agamemnon        2020    0
  2 Ajax             2010    0
  3 Ajax             2011    0
  4 Ajax             2012    0
  5 Ajax             2013    0
  6 Ajax             2014    0
  7 Ajax-Egerton     2016    1
  8 Aldo             2016    0
  9 Aldo             2017    0
 10 Aldo-Knottboy    2018    1

首先,我想按名称和波段类型对我的数据集进行分组。为此,我知道我可以使用以下代码。

df <- band_list %>% group_by(`BandName(Stallion-Tag)`, BandType)

其次,我想按年份分组。意思是,我想将具有相同名称和乐队类型以及连续年份的乐队分组为一组,并计算出现的总数。 例如,Ajax(第 2-6 行)以相同的名称和类型出现五次,并且还在连续的年份(2010-2014)内出现,所以我想得到结果 5.

occurence_band <- band_list %>% count(`BandName(Stallion-Tag)`, BandType)

我确实用我的代码得到了这个,但我有一些数据,其中缺少一年,但名称和类型保持不变。例如,

   BandName Year BandType
40 Arno     2014    0
41 Arno     2015    0
42 Arno     2017    0 
43 Arno     2018    0
44 Arno     2020    0

使用 R 上面的相同代码会给我 Arno 5 的计数,但我想在这里为 Arno 设置三个不同的组: Arno(2014-2015)第二条,Arno(2017-2018)第二条,Arno(2020)第一条。我需要它像这样分开,因为它对我必须做的进一步分析很重要。 我认为编写自己的函数可能会解决我的问题,但我只编写了一次自己的函数,所以我现在知道如何告诉 R 查找连续的年份并计算它(但我没有找到任何有效的方法)。任何帮助将不胜感激。

此处使用 data.table 包:

library(data.table)
dat <- as.data.table(test)
result <- dat[, .(count= .SD[, .N, cumsum(c(1L, diff(Year) > 1L))]$N), .(BandName, BandType)]

使用逻辑 cumsum 技巧创建一个 Runs 变量,并将此变量包含在分组变量中。然后统计子组。

df1 <- read.table(text = "
   BandName Year BandType
40 Arno     2014    0
41 Arno     2015    0
42 Arno     2017    0 
43 Arno     2018    0
44 Arno     2020    0
", header = TRUE)

suppressPackageStartupMessages(library(dplyr))

df1 %>%
  mutate(Runs = cumsum(c(1L, diff(Year)) > 1L)) %>%
  group_by(BandName, BandType, Runs) %>%
  summarize(Count = n(), .groups = "drop") %>%
  select(-Runs)
#> # A tibble: 3 x 3
#>   BandName BandType Count
#>   <chr>       <int> <int>
#> 1 Arno            0     2
#> 2 Arno            0     2
#> 3 Arno            0     1

reprex package (v2.0.1)

创建于 2022-03-13

这也适用于下面的 df2

df2 <- read.table(text = "
BandName         Year BandType
  1 Agamemnon        2020    0
  2 Ajax             2010    0
  3 Ajax             2011    0
  4 Ajax             2012    0
  5 Ajax             2013    0
  6 Ajax             2014    0
  7 Ajax-Egerton     2016    1
  8 Aldo             2016    0
  9 Aldo             2017    0
 10 Aldo-Knottboy    2018    1
", header = TRUE)

df2 %>%
  mutate(Runs = cumsum(c(1L, diff(Year)) > 1L)) %>%
  group_by(BandName, BandType, Runs) %>%
  summarize(Count = n(), .groups = "drop") %>%
  select(-Runs)
#> # A tibble: 5 x 3
#>   BandName      BandType Count
#>   <chr>            <int> <int>
#> 1 Agamemnon            0     1
#> 2 Ajax                 0     5
#> 3 Ajax-Egerton         1     1
#> 4 Aldo                 0     2
#> 5 Aldo-Knottboy        1     1

reprex package (v2.0.1)

创建于 2022-03-13