【问题标题】:Generating a rolling tally based on criterion (R) [duplicate]根据标准(R)生成滚动计数[重复]
【发布时间】:2020-10-07 17:46:21
【问题描述】:

问题描述

我正在处理美国冲突事件的电子表格。每行代表一个事件,并包含地理和时间信息。冲突事件往往以“波”的形式发生(相对紧密的时间分组)。我已经为每一波生成了一个身份变量,并想创建一个变量来衡量这些冲突事件在每一波过程中的地理分布。

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中发生冲突的区域的数量。在整个浪潮中,我预计区域的数量会增加,并且我希望 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 变量?

提前感谢您 - 非常感谢。

【问题讨论】:

    标签: r criteria rolling-computation


    【解决方案1】:

    保留整个数据集的 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
    
    

    【讨论】:

    • 关卡的使用很巧妙
    • 嗨艾伦 - 看起来此代码创建的 geo_disp 变量不会随着时间的推移而建立。有没有办法让它跟踪任何给定观察中发生冲突事件的区域总数?谢谢!
    • @Yasha 检查我的更新 - 你是这个意思吗?
    • @Allan Cameron - 天哪,我想你解决了这个问题。非常感谢!
    【解决方案2】:

    如果您不介意在同一波中删除重复区域,您可以使用 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"))
    
    

    【讨论】:

    • 感谢您的帮助。我希望不要从数据集中删除观察结果。我非常感谢 dput() 的帮助 - 我下次会使用它。
    【解决方案3】:

    我们可以通过'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))
    

    【讨论】:

    • 嗨@akrun - 非常感谢。当我运行您提供的代码时,geo_disp 变量似乎没有累积。我希望这个变量将跟踪事件在波浪过程中发生的区域数量。
    • @Yasha 也许,这是一个不同的例子。对不起
    • 没有理由道歉!非常感谢您的帮助。
    【解决方案4】:

    以前的答案解决了这个问题,但要添加一个累积计数(我认为 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
    

    【讨论】:

    • 感谢您的帮助。当我运行您的代码时,我收到此错误消息:“:=(count, cummax(match(region, unique(region)))) 中的错误:检查 is.data.table(DT) == TRUE。否则, := 和 :=(...) 被定义为在 j 中使用,仅一次且以特定方式使用。请参阅 help(":=")。"
    • 对不起@Yasha,我没有把library(data.table)放在顶部。现在它应该可以工作了。
    • 是的,现在可以了!哇,非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-15
    • 2013-10-04
    • 1970-01-01
    • 2016-05-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多