r - 按阈值过滤数据,包括第一个超过阈值的值

标签 r dplyr

这似乎是一个简单的问题,但我很难理解它。我有一个按出生地区划分的人口位置数据框,我正在尝试筛选总人口超过阈值(在本例中为 50%)的地区。

例如,对于每个位置,我需要能够说“在费尔菲尔德县,大多数外国出生的人口出生在中美洲、南美洲或加勒比地区。”为了能够以这种方式表述,我需要包括第一个超过 50% 标记的国家/地区。

我的数据的删节版本以及每个位置的前几行位于此处:

library(tidyverse)

df <- structure(list(name = c("Fairfield County", "Fairfield County", 
                              "Fairfield County", "Fairfield County", "Greater Hartford", "Greater Hartford", 
                              "Greater Hartford", "Greater Hartford", "Greater Hartford"), 
                     subregion = c("South America", "Central America", "Caribbean", 
                                   "South Central Asia", "Caribbean", "Eastern Europe", "South Central Asia", 
                                   "South America", "Southern Europe"), 
                     pop = c(40565, 33919, 32044, 17031, 26939, 23765, 20153, 14384, 9309), 
                     cum_share = c(0.2, 0.38, 0.54, 0.62, 0.2, 0.37, 0.51, 0.62, 0.69)), 
                     class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -9L))

df %>%
  group_by(name) %>%
  top_n(4, pop)
#> # A tibble: 8 x 4
#> # Groups:   name [2]
#>   name             subregion            pop cum_share
#>   <chr>            <chr>              <dbl>     <dbl>
#> 1 Fairfield County South America      40565      0.2 
#> 2 Fairfield County Central America    33919      0.38
#> 3 Fairfield County Caribbean          32044      0.54
#> 4 Fairfield County South Central Asia 17031      0.62
#> 5 Greater Hartford Caribbean          26939      0.2 
#> 6 Greater Hartford Eastern Europe     23765      0.37
#> 7 Greater Hartford South Central Asia 20153      0.51
#> 8 Greater Hartford South America      14384      0.62

我的第一个计划是过滤累计份额小于或等于 51% 的地区,即排名靠前的地区,直到达到大多数人口。问题在于,由于这些份额不是连续分布,因此设置这样的截止点是行不通的,因为我需要包括累积份额占多数的第一个区域。

df %>%
  filter(cum_share <= 0.51)
#> # A tibble: 5 x 4
#>   name             subregion            pop cum_share
#>   <chr>            <chr>              <dbl>     <dbl>
#> 1 Fairfield County South America      40565      0.2 
#> 2 Fairfield County Central America    33919      0.38
#> 3 Greater Hartford Caribbean          26939      0.2 
#> 4 Greater Hartford Eastern Europe     23765      0.37
#> 5 Greater Hartford South Central Asia 20153      0.51

通过与第一个快照的比较,您可以看到,大哈特福德的工作正如我所期望的那样。但费尔菲尔德县应该包括加勒比地区,其累计份额为 54%;通过设置 51% 的阈值进行过滤,加勒比地区不包括在内。我想要得到的是这样的:

#> # A tibble: 6 x 4
#>   name             subregion            pop cum_share
#>   <chr>            <chr>              <dbl>     <dbl>
#> 1 Fairfield County South America      40565      0.2 
#> 2 Fairfield County Central America    33919      0.38
#> 3 Fairfield County Caribbean          32044      0.54
#> 4 Greater Hartford Caribbean          26939      0.2 
#> 5 Greater Hartford Eastern Europe     23765      0.37
#> 6 Greater Hartford South Central Asia 20153      0.51

这里,还包括份额超过50%的第一名。我可以手动过滤,但实际上我是按国家/地区而不是世界地区进行此操作,并且针对 18 个位置,因此它变得很笨拙。

提前致谢!

编辑:哇,我意识到自己的愚蠢了 - 我可以按升序顺序计算人口的累积份额,而不是降序 ,然后轻松过滤该阈值超过 50% 的地方。不过,我将保留这一点,以帮助那些无法通过这种方式控制数据的人。

最佳答案

For example, for each location I need to be able to say something like, "In Fairfield County, a majority of the foreign-born population were born in Central and South America or the Caribbean."

对于满足条件后停止的一般情况,有 filter(lag(cumsum(cond), default=FALSE) == 0)

> df %>% group_by(name) %>% filter(cumsum(lag(cum_share > 0.5, default = FALSE)) == 0)
# A tibble: 6 x 4
# Groups:   name [2]
              name          subregion   pop cum_share
             <chr>              <chr> <dbl>     <dbl>
1 Fairfield County      South America 40565      0.20
2 Fairfield County    Central America 33919      0.38
3 Fairfield County          Caribbean 32044      0.54
4 Greater Hartford          Caribbean 26939      0.20
5 Greater Hartford     Eastern Europe 23765      0.37
6 Greater Hartford South Central Asia 20153      0.51

OP 在单调条件的情况下确定了一个更简单的过滤器(即,在第一次满足条件后,向量的后续元素也这样做):filter(lag(cum_share, default = 0) <= 0.5) .

可能有一个很好的方法将其包装在函数中(根据用户输入改变 .cond ;改变 .keep 标准 = cumsum(lag(.cond, default=FALSE) == 0) ;过滤器;删除 .cond.keep ),但我没有tidyverse NSE 技能是第一步。

关于r - 按阈值过滤数据,包括第一个超过阈值的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51827428/

相关文章:

r - 多层 : assign functions to cluster

r - left_join 在键有空格时产生 NA

r - dplyr 条件过滤组

r - 尝试创建森林图时出现 R 代码错误

r - 如何在图例键周围有选择地添加框

r - 改变线宽(粗细) sjPlot sjp.int R

以 tidyeval 的方式删除列

java - 二维点集的环绕

r - 在 R 中添加简单的图例来绘图

r - 数据变异的查找函数