根据标准 (R) 生成滚动计数
Generating a rolling tally based on criterion (R)
问题描述
我正在处理美国冲突事件的电子表格。每行代表一个事件并包含地理和时间信息。冲突事件往往发生在 'waves'(相对紧密的时间分组)中。我已经为每一波生成了一个身份变量,并想创建一个变量来衡量这些冲突事件在每一波过程中的地理分布。
我wanted to do this in Excel,但不幸的是我没有可用的动态数组公式。在升级到新版本之前Excel,我想看看在R中是否可以。数据已经按地区、日期和波次排序了。
数据说明
数据集结构如下:
Country Region Date Event Wave
------- ------- ------ ------- ------
USA Vermont 5/1/2017 Strike Wave 1
USA Vermont 5/2/2017 Strike Wave 1
USA New Hamp. 5/3/2017 Strike Wave 1
USA Vermont 5/3/2017 Strike Wave 1
USA Maine 5/4/2017 Strike Wave 1
USA Washingt. 8/16/2018 Riot Wave 2
USA Washingt. 8/18/2018 Riot Wave 2
USA Oregon 8/18/2018 Protest Wave 2
USA Californ. 8/19/2018 Riot Wave 2
USA Nevada 8/20/2018 Protest Wave 2
USA Idaho 8/20/2018 Riot Wave 2
我想创造什么
我想创建一个变量 ("geo_disp") 来记录在给定的 wave[=38] 中发生冲突的 region 的数量=].整个浪潮中,我希望区域数量会增加,我希望geo_disp变量记录这一点。
你会注意到,当两个事件发生在同一天但发生在不同的地点时,两者都会记录在地区总数中。
这是我想要的数据:
Country Region Date Event Wave geo_disp
------- ------- ------ ------- ------ --------
USA Vermont 5/1/2017 Strike Wave 1 1
USA Vermont 5/2/2017 Strike Wave 1 1
USA New Hamp. 5/3/2017 Strike Wave 1 2
USA Vermont 5/3/2017 Strike Wave 1 2
USA Maine 5/4/2017 Strike Wave 1 3
USA Washingt. 8/16/2018 Riot Wave 2 1
USA Washingt. 8/18/2018 Riot Wave 2 2
USA Oregon 8/18/2018 Protest Wave 2 2
USA Californ. 8/19/2018 Riot Wave 2 3
USA Nevada 8/20/2018 Protest Wave 2 5
USA Idaho 8/20/2018 Riot Wave 2 5
如何使用 R 创建 geo_disp 变量?
提前致谢 - 非常感谢。
如果您不介意删除同一 wave 中的重复区域,您可以使用 tidyverse 尝试这种方法:
library(tidyverse)
df <- tribble(
~Country, ~Region, ~Date, ~Event, ~Wave,
'USA', 'Vermont', '5/1/2017', 'Strike', 'Wave 1',
'USA', 'Vermont', '5/2/2017', 'Strike', 'Wave 1',
'USA', 'New Hamp.', '5/3/2017', 'Strike', 'Wave 1',
'USA', 'Vermont', '5/3/2017', 'Strike', 'Wave 1',
'USA', 'Maine', '5/4/2017', 'Strike', 'Wave 1',
'USA', 'Washingt.', '8/16/2018', 'Riot', 'Wave 2',
'USA', 'Washingt.', '8/18/2018', 'Riot', 'Wave 2',
'USA', 'Oregon', '8/18/2018', 'Protest', 'Wave 2',
'USA', 'Californ.', '8/19/2018', 'Riot', 'Wave 2',
'USA', 'Nevada', '8/20/2018', 'Protest', 'Wave 2',
'USA', 'Idaho', '8/20/2018', 'Riot', 'Wave 2'
)
df %>% distinct(Region, .keep_all = T) %>% group_by(Wave) %>% mutate(geo_disp = 1:n())
请注意,dput() 是使数据易于在 R 中共享的好方法。
> dput(df)
structure(list(Country = c("USA", "USA", "USA", "USA", "USA",
"USA", "USA", "USA", "USA", "USA", "USA"), Region = c("Vermont",
"Vermont", "New Hamp.", "Vermont", "Maine", "Washingt.", "Washingt.",
"Oregon", "Californ.", "Nevada", "Idaho"), Date = c("5/1/2017",
"5/2/2017", "5/3/2017", "5/3/2017", "5/4/2017", "8/16/2018",
"8/18/2018", "8/18/2018", "8/19/2018", "8/20/2018", "8/20/2018"
), Event = c("Strike", "Strike", "Strike", "Strike", "Strike",
"Riot", "Riot", "Protest", "Riot", "Protest", "Riot"), Wave = c("Wave 1",
"Wave 1", "Wave 1", "Wave 1", "Wave 1", "Wave 2", "Wave 2", "Wave 2",
"Wave 2", "Wave 2", "Wave 2")), row.names = c(NA, -11L), class = c("tbl_df",
"tbl", "data.frame"))
保留整个数据集的 dplyr 解决方案。
library(dplyr)
df %>% group_by(Wave) %>% mutate(disp_geo = cumsum(!duplicated(Region)))
#> # A tibble: 11 x 6
#> # Groups: Wave [2]
#> Country Region Date Event Wave disp_geo
#> <chr> <chr> <chr> <chr> <chr> <int>
#> 1 USA Vermont 5/1/2017 Strike Wave 1 1
#> 2 USA Vermont 5/2/2017 Strike Wave 1 1
#> 3 USA New Hamp. 5/3/2017 Strike Wave 1 2
#> 4 USA Vermont 5/3/2017 Strike Wave 1 2
#> 5 USA Maine 5/4/2017 Strike Wave 1 3
#> 6 USA Washingt. 8/16/2018 Riot Wave 2 1
#> 7 USA Washingt. 8/18/2018 Riot Wave 2 1
#> 8 USA Oregon 8/18/2018 Protest Wave 2 2
#> 9 USA Californ. 8/19/2018 Riot Wave 2 3
#> 10 USA Nevada 8/20/2018 Protest Wave 2 4
#> 11 USA Idaho 8/20/2018 Riot Wave 2 5
按'Wave'分组后我们可以使用match
library(data.table)
setDT(df)[, geo_disp := match(Region, unique(Region)), Wave]
或与dplyr
library(dplyr)
df %>%
group_by(Wave) %>%
mutate(geo_disp = match(Region, unique(Region))
以前的答案解决了这个问题,但要将其添加到累积计数(我认为 Yasha 正在努力实现)你会做:
library(data.table)
set.seed(1)
toy_data = data.table(
region = sample(LETTERS[1:3], 10, replace = T),
wave = c(rep(1,5),rep(2,5))
)
toy_data[,count:=cummax(match(region, unique(region))), wave]
# > toy_data
# region wave count
# 1: A 1 1
# 2: C 1 2
# 3: A 1 2
# 4: B 1 3
# 5: A 1 3
# 6: C 2 1
# 7: C 2 1
# 8: B 2 2
# 9: B 2 2
# 10: C 2 2
问题描述
我正在处理美国冲突事件的电子表格。每行代表一个事件并包含地理和时间信息。冲突事件往往发生在 'waves'(相对紧密的时间分组)中。我已经为每一波生成了一个身份变量,并想创建一个变量来衡量这些冲突事件在每一波过程中的地理分布。
我wanted to do this in Excel,但不幸的是我没有可用的动态数组公式。在升级到新版本之前Excel,我想看看在R中是否可以。数据已经按地区、日期和波次排序了。
数据说明
数据集结构如下:
Country Region Date Event Wave
------- ------- ------ ------- ------
USA Vermont 5/1/2017 Strike Wave 1
USA Vermont 5/2/2017 Strike Wave 1
USA New Hamp. 5/3/2017 Strike Wave 1
USA Vermont 5/3/2017 Strike Wave 1
USA Maine 5/4/2017 Strike Wave 1
USA Washingt. 8/16/2018 Riot Wave 2
USA Washingt. 8/18/2018 Riot Wave 2
USA Oregon 8/18/2018 Protest Wave 2
USA Californ. 8/19/2018 Riot Wave 2
USA Nevada 8/20/2018 Protest Wave 2
USA Idaho 8/20/2018 Riot Wave 2
我想创造什么
我想创建一个变量 ("geo_disp") 来记录在给定的 wave[=38] 中发生冲突的 region 的数量=].整个浪潮中,我希望区域数量会增加,我希望geo_disp变量记录这一点。
你会注意到,当两个事件发生在同一天但发生在不同的地点时,两者都会记录在地区总数中。
这是我想要的数据:
Country Region Date Event Wave geo_disp
------- ------- ------ ------- ------ --------
USA Vermont 5/1/2017 Strike Wave 1 1
USA Vermont 5/2/2017 Strike Wave 1 1
USA New Hamp. 5/3/2017 Strike Wave 1 2
USA Vermont 5/3/2017 Strike Wave 1 2
USA Maine 5/4/2017 Strike Wave 1 3
USA Washingt. 8/16/2018 Riot Wave 2 1
USA Washingt. 8/18/2018 Riot Wave 2 2
USA Oregon 8/18/2018 Protest Wave 2 2
USA Californ. 8/19/2018 Riot Wave 2 3
USA Nevada 8/20/2018 Protest Wave 2 5
USA Idaho 8/20/2018 Riot Wave 2 5
如何使用 R 创建 geo_disp 变量?
提前致谢 - 非常感谢。
如果您不介意删除同一 wave 中的重复区域,您可以使用 tidyverse 尝试这种方法:
library(tidyverse)
df <- tribble(
~Country, ~Region, ~Date, ~Event, ~Wave,
'USA', 'Vermont', '5/1/2017', 'Strike', 'Wave 1',
'USA', 'Vermont', '5/2/2017', 'Strike', 'Wave 1',
'USA', 'New Hamp.', '5/3/2017', 'Strike', 'Wave 1',
'USA', 'Vermont', '5/3/2017', 'Strike', 'Wave 1',
'USA', 'Maine', '5/4/2017', 'Strike', 'Wave 1',
'USA', 'Washingt.', '8/16/2018', 'Riot', 'Wave 2',
'USA', 'Washingt.', '8/18/2018', 'Riot', 'Wave 2',
'USA', 'Oregon', '8/18/2018', 'Protest', 'Wave 2',
'USA', 'Californ.', '8/19/2018', 'Riot', 'Wave 2',
'USA', 'Nevada', '8/20/2018', 'Protest', 'Wave 2',
'USA', 'Idaho', '8/20/2018', 'Riot', 'Wave 2'
)
df %>% distinct(Region, .keep_all = T) %>% group_by(Wave) %>% mutate(geo_disp = 1:n())
请注意,dput() 是使数据易于在 R 中共享的好方法。
> dput(df)
structure(list(Country = c("USA", "USA", "USA", "USA", "USA",
"USA", "USA", "USA", "USA", "USA", "USA"), Region = c("Vermont",
"Vermont", "New Hamp.", "Vermont", "Maine", "Washingt.", "Washingt.",
"Oregon", "Californ.", "Nevada", "Idaho"), Date = c("5/1/2017",
"5/2/2017", "5/3/2017", "5/3/2017", "5/4/2017", "8/16/2018",
"8/18/2018", "8/18/2018", "8/19/2018", "8/20/2018", "8/20/2018"
), Event = c("Strike", "Strike", "Strike", "Strike", "Strike",
"Riot", "Riot", "Protest", "Riot", "Protest", "Riot"), Wave = c("Wave 1",
"Wave 1", "Wave 1", "Wave 1", "Wave 1", "Wave 2", "Wave 2", "Wave 2",
"Wave 2", "Wave 2", "Wave 2")), row.names = c(NA, -11L), class = c("tbl_df",
"tbl", "data.frame"))
保留整个数据集的 dplyr 解决方案。
library(dplyr)
df %>% group_by(Wave) %>% mutate(disp_geo = cumsum(!duplicated(Region)))
#> # A tibble: 11 x 6
#> # Groups: Wave [2]
#> Country Region Date Event Wave disp_geo
#> <chr> <chr> <chr> <chr> <chr> <int>
#> 1 USA Vermont 5/1/2017 Strike Wave 1 1
#> 2 USA Vermont 5/2/2017 Strike Wave 1 1
#> 3 USA New Hamp. 5/3/2017 Strike Wave 1 2
#> 4 USA Vermont 5/3/2017 Strike Wave 1 2
#> 5 USA Maine 5/4/2017 Strike Wave 1 3
#> 6 USA Washingt. 8/16/2018 Riot Wave 2 1
#> 7 USA Washingt. 8/18/2018 Riot Wave 2 1
#> 8 USA Oregon 8/18/2018 Protest Wave 2 2
#> 9 USA Californ. 8/19/2018 Riot Wave 2 3
#> 10 USA Nevada 8/20/2018 Protest Wave 2 4
#> 11 USA Idaho 8/20/2018 Riot Wave 2 5
按'Wave'分组后我们可以使用match
library(data.table)
setDT(df)[, geo_disp := match(Region, unique(Region)), Wave]
或与dplyr
library(dplyr)
df %>%
group_by(Wave) %>%
mutate(geo_disp = match(Region, unique(Region))
以前的答案解决了这个问题,但要将其添加到累积计数(我认为 Yasha 正在努力实现)你会做:
library(data.table)
set.seed(1)
toy_data = data.table(
region = sample(LETTERS[1:3], 10, replace = T),
wave = c(rep(1,5),rep(2,5))
)
toy_data[,count:=cummax(match(region, unique(region))), wave]
# > toy_data
# region wave count
# 1: A 1 1
# 2: C 1 2
# 3: A 1 2
# 4: B 1 3
# 5: A 1 3
# 6: C 2 1
# 7: C 2 1
# 8: B 2 2
# 9: B 2 2
# 10: C 2 2