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 的结果是 cbind
和 id
并通过管道传输到计数指令。然后保存在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)
尽管如此,还是谢谢大家的解决方案,非常感谢。
我正在使用 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 的结果是 cbind
和 id
并通过管道传输到计数指令。然后保存在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)
尽管如此,还是谢谢大家的解决方案,非常感谢。