R - dplyr- 减少数据包 'storms'

R - dplyr- Reducing data package 'storms'

我正在使用 dplyr 和数据包 'storms'。

我需要一个 table,其中我将每个测量的风暴都列在一列中。然后我想给每一行一个ID。

到目前为止我有

storm_ID <- storms %>%
  select(year,month,name) %>% 
  group_by(year,month,name) %>% 
  summarise(ID = n())
storm_ID

View(storm_ID)

唯一的问题是它对我没有任何作用。

我不太明白我怎么能看到 table 中的每一场风暴。我之前按名称对它们进行了排序。然后我得到214风暴。然而,同名风暴每隔几年就会出现。

最后我想要这样的东西:

name   |   year   |   month   |   day   |    ID 

  |          |          |          |          |
Zeta       2005        12          31       Zeta1 
Zeta       2006        1           1        Zeta1
  |          |          |          |          |
Zeta       2020        10          24       Zeta2

为此,我需要知道 2 年内是否发生过风暴(即从 2005-12-31 到 2006-01-01),但这只能算作一场风暴。

之后我应该能够评估每次风暴的持续时间、风速差异和压力差异。我已经用错误的排序评估了。

帮助会很好。

提前致谢。

给你的第一个问题:

storm_ID <- storms %>%
  select(year,month,name) %>% 
  group_by(year,month,name) %>%
  mutate(ID = stringr::str_c(name, cur_group_id()))

这将创建一个独特的 Storm-Name-ID,例如Amy1、Amy2 等

这是检查风暴是否连续发生的方法

storms %>%
  group_by(name) %>%
  mutate(consec_helper = cumsum(c(1, diff(year) != 1))) %>%
  group_by(name, consec_helper) %>%
  filter(n() > 1)

我发现这只适用于 Zeta

 name   year
  <chr> <dbl>
1 Zeta   2005
2 Zeta   2006

如果您将持续到第二天的风暴算作一次,但没有间隔,没有同名风暴的日子,那么以下代码可能就是您想要的。
变量 Thresh 设置为将风暴计为同一风暴的最大连续天数。

suppressPackageStartupMessages(library(dplyr))

data("storms", package = "dplyr")

Thresh <- 5

storms %>%
  count(name, year, month, day) %>%
  group_by(name) %>%
  mutate(Date = as.Date(ISOdate(year, month, day)),
         DDiff = c(0, diff(Date)) > Thresh,
         DDiff = cumsum(DDiff)) %>%
  group_by(name, DDiff) %>%
  mutate(name = ifelse(DDiff > 0, paste(name, cur_group_id(), sep = "."), name)) %>%
  ungroup() %>%
  group_by(name) %>%
  summarise(name = first(name),
            year = first(year),
            n = sum(n))
#> # A tibble: 512 x 3
#>    name      year     n
#>    <chr>    <dbl> <int>
#>  1 AL011993  1993     8
#>  2 AL012000  2000     4
#>  3 AL021992  1992     5
#>  4 AL021994  1994     6
#>  5 AL021999  1999     4
#>  6 AL022000  2000    12
#>  7 AL022001  2001     5
#>  8 AL022003  2003     4
#>  9 AL022006  2006     5
#> 10 AL031987  1987    32
#> # ... with 502 more rows

reprex package (v2.0.1)

于 2022-04-15 创建

编辑

看到OP的回答后,我修改了我的,现在几乎一样了。

主要区别在于,即使将有记录的天数 Thresh 增加到 5,风暴 Dorian 在 2013 年 7 月 27 日和 2013 年 8 月 2 日之间连续 5 天没有记录. 还是一样,应该算是一场风暴罢了。要获得此结果,请将 Thresh 增加到适当的值,例如 30(天),现在输出匹配。

我这样保留它是为了说明这一点并说明变量 Thresh 的含义。

在接下来的代码中,我将上面代码的结果分配给 data.frame rui 并且 OP 的结果是 cbindid并通过管道传输到计数指令。然后保存在storm_count。从我的 name 列中删除 id 后,将两个输出与 anti_join 的差异进行比较。

suppressPackageStartupMessages(library(dplyr))

data("storms", package = "dplyr")

Thresh <- 5

storms %>%
  count(name, year, month, day) %>%
  group_by(name) %>%
  mutate(Date = as.Date(ISOdate(year, month, day)),
         DDiff = c(0, diff(Date)) > Thresh,
         DDiff = cumsum(DDiff)) %>%
  group_by(name, DDiff) %>%
  mutate(name = ifelse(DDiff > 0, paste(name, cur_group_id(), sep = "."), name)) %>%
  ungroup() %>%
  group_by(name) %>%
  summarise(name = first(name),
            year = first(year),
            n = sum(n)) -> rui


id <- c()
j <- 1
k <- 1
for(i in storms$name) {
  if(k-1 == 0){
    id <- append(id, j)
    k <- k+1
    next
  }
  if(i != storms$name[k-1])
  {
    j <- j+1
  }
  id <- append(id, j)
  k <- k+1
}

cbind(storms, id) %>% 
  count(name, id) -> storm_count

# two rows
anti_join(
  rui %>% mutate(name = sub("\.\d+$", "", name)), 
  storm_count,
  by = c("name", "n")
)
#> # A tibble: 2 x 3
#>   name    year     n
#>   <chr>  <dbl> <int>
#> 1 Dorian  2013    16
#> 2 Dorian  2013     4

# just one row
anti_join(
  storm_count,
  rui %>% mutate(name = sub("\.\d+$", "", name)),
  by = c("name", "n")
)
#>     name  id  n
#> 1 Dorian 397 20

# see here the dates of 2013-07-27 and 2013-08-02
storms %>%
  filter(name == "Dorian", year == 2013) %>%
  count(name, year, month, day)
#> # A tibble: 7 x 5
#>   name    year month   day     n
#>   <chr>  <dbl> <dbl> <int> <int>
#> 1 Dorian  2013     7    23     1
#> 2 Dorian  2013     7    24     4
#> 3 Dorian  2013     7    25     4
#> 4 Dorian  2013     7    26     4
#> 5 Dorian  2013     7    27     3
#> 6 Dorian  2013     8     2     1
#> 7 Dorian  2013     8     3     3

reprex package (v2.0.1)

于 2022-04-15 创建

感谢您提供的方法,不幸的是,并非所有方法都是合适的解决方案。

我向我的教授求助,他说我可以用循环开始查询。 (我没想到会得到答案)所以我后来检查了名字,看看他们是否改变了。数据集按日期排序,因此如果不是同一个风暴,Zeta 不会连续出现。

我目前的解决方案是:

install.packages(dplyr)
library(dplyr)

id <- c()
j <- 1
k <- 1
for(i in storms$name) {
  if(k-1 == 0){
    id <- append(id, j)
    k <- k+1
    next
  }
  if(i != storms$name[k-1])
  {
    j <- j+1
  }
  id <- append(id, j)
  k <- k+1
}
storms <- cbind(storms, id)
View(storms)

我现在已经手动检查了数据集,认为它是解决我的问题的合适方法。

这让我想到了 511 种不同的风暴。 (截至 22-04-15)

尽管如此,还是谢谢大家的解决方案,非常感谢。