【问题标题】:subsetting Panel Data conditional on consecutive strings of length以连续的长度字符串为条件的子集面板数据
【发布时间】:2018-07-05 01:17:46
【问题描述】:

我一直在尝试使用 dplyr 对一些面板数据进行子集化,即组内的 id。

我想精确计算每个组内的所有ids,grp 有一个NUM 系列,最小值小于 2,最大值大于 2。我已经构建了一个 minimal 下面的工作示例应该可以说明问题。

我一直在与filter()row_number() == c(1,n()) 合作,并试图将其分离并合并,即不同类型的_join,它重新组合在一起,但我被困住了,我现在转向 SO 社区寻求帮助。

我得到了什么

像这样的tibble

df <- tibble(id = rep(0:1, c(8, 13)), grp = rep(c("01", "02"), c(13, 8)),
             NUM = c(-4, -3, -2, -1, 1, 2, 3, 4, -3, -2, -1,
                      1, 2, -3, -2, -1, 1, 2, 3, 4, 5)) %>% group_by(id, grp)
df %>% print(n=21)
#> # A tibble: 21 x 3
#> # Groups:   id, grp [3]
#>       id   grp   NUM
#>    <int> <chr> <dbl>
#>  1     0    01    -4
#>  2     0    01    -3
#>  3     0    01    -2
#>  4     0    01    -1
#>  5     0    01     1
#>  6     0    01     2
#>  7     0    01     3
#>  8     0    01     4
#>  9     1    01    -3
#> 10     1    01    -2
#> 11     1    01    -1
#> 12     1    01     1
#> 13     1    01     2
#> 14     1    02    -3
#> 15     1    02    -2
#> 16     1    02    -1
#> 17     1    02     1
#> 18     1    02     2
#> 19     1    02     3
#> 20     1    02     4
#> 21     1    02     5

我想要得到/想要的结果

df_out <- tibble(id = rep(0:1, c(9, 8)),
             grp = rep(c("01", "02"), c(9, 8)),
             NUM = c(-4, -3, -2, -1, 1, 2, 3,
           4, 5, -3, -2, -1, 1, 2, 3, 4, 5)) %>%  group_by(id, grp)
df_out
#> # A tibble: 17 x 3
#> # Groups:   id, grp [3]
#>       id   grp   NUM
#>    <int> <chr> <dbl>
#>  1     0    01    -4
#>  2     0    01    -3
#>  3     0    01    -2
#>  4     0    01    -1
#>  5     0    01     1
#>  6     0    01     2
#>  7     0    01     3
#>  8     0    01     4
#>  9     1    02    -3
#> 10     1    02    -2
#> 11     1    02    -1
#> 12     1    02     1
#> 13     1    02     2
#> 14     1    02     3
#> 15     1    02     4
#> 16     1    02     5

【问题讨论】:

    标签: r dplyr subset panel-data


    【解决方案1】:

    像这样?

    library(dplyr)
    filter(df, any(NUM > 2) & any(NUM < -2))
    
    # A tibble: 16 x 3
    # Groups:   id, grp [2]
          id grp     NUM
       <int> <chr> <dbl>
     1     0 01    -4.00
     2     0 01    -3.00
     3     0 01    -2.00
     4     0 01    -1.00
     5     0 01     1.00
     6     0 01     2.00
     7     0 01     3.00
     8     0 01     4.00
     9     1 02    -3.00
    10     1 02    -2.00
    11     1 02    -1.00
    12     1 02     1.00
    13     1 02     2.00
    14     1 02     3.00
    15     1 02     4.00
    16     1 02     5.00
    

    此外,如果要对一个精确值进行子集化,假设第一个NUM-3,最后一个NUM5,即原始数据中的第9-16 行,可以这样做像这样,

    df %>%
      group_by(id, grp) %>%
      mutate(first = first(NUM)
            ,last = last(NUM)) %>%
      filter(-3 == first & 5 == last) %>%
      select(-first, -last)  
    #> # A tibble: 8 x 3
    #> # Groups:   id, grp [1]
    #>      id   grp   NUM
    #>   <int> <chr> <dbl>
    #> 1     1    02    -3
    #> 2     1    02    -2
    #> 3     1    02    -1
    #> 4     1    02     1
    #> 5     1    02     2
    #> 6     1    02     3
    #> 7     1    02     4
    #> 8     1    02     5
    

    以上灵感来自this SO answer

    【讨论】:

    • 感谢您的及时回复!我意识到我也做了最小的工作示例minimal。我确实有 NUM 字符串不相等的情况,例如-3, -2, -1, 1, 2 那不应该被计算在内。我会将我的 mwe 更新为类似 df &lt;- tibble(id = rep(0:1, c(8, 13)), grp = rep(c("01", "02"), c(13, 8)), NUM = c(-4, -3, -2, -1, 1, 2, 3, 4, -3, -2, -1, 1, 2, -3, -2, -1, 1, 2, 3, 4, 5)) %&gt;% group_by(id, grp) 的内容(但可能需要一分钟,因为我必须考虑清楚)
    • 甚至可以将其缩短为filter(df, any(NUM &gt; abs(2)))
    • @EricFail,感谢您的编辑,但我建议您将其发布为该问题的另一个答案。第 6 行也应该是 select(-first, -last)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-02
    • 1970-01-01
    • 2015-06-24
    • 1970-01-01
    • 2014-07-20
    • 2014-05-08
    相关资源
    最近更新 更多