【问题标题】:flitering with dplyr's filter() – using relational operators使用 dplyr filter() 过滤——使用关系运算符
【发布时间】:2018-07-03 20:08:49
【问题描述】:

我被困住了。如何使用dplyr's filter()同时将我们两个关系运算符作为组内组内的过滤器@

我得到了什么

数据,

# install.packages(c("tidyverse"), dependencies = TRUE)
library(tibble)
tbl <- structure(list(id1 = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L,
           2L, 2L, 2L, 2L, 2L, 2L), id2 = c("x_02", "x_02", "x_02", "x_02", "x_02", "x_02",
           "x_02", "x_02", "x_02", "x_02", "x_02", "x_02", "x_02", "x_03", "x_03", "x_03",
           "x_03", "x_03", "x_03", "x_03", "x_03"), x = c(-4L, -3L, -2L, -1L, 1L, 2L, 3L,
           4L, 5L, -2L, -1L, 1L, 2L, -2L, -1L, 1L, 2L, 3L, 4L, 5L, 6L)),
           class = c("grouped_df", "tbl_df", "tbl", "data.frame"), row.names = c(NA, -21L),
           vars = c("id1", "id2"), drop = TRUE, .Names = c("id1", "id2", "x"),
           indices = list(0:8, 9:12, 13:20), group_sizes = c(9L, 4L, 8L),
           biggest_group_size = 9L, labels = structure(list(id1 = c(1L, 2L, 2L),
           id2 = c("x_02", "x_02", "x_03")), class = "data.frame", row.names = c(NA, -3L),
           vars = c("id1", "id2"), drop = TRUE, .Names = c("id1", "id2")))

tbl
#> # A tibble: 21 x 3
#> # Groups:   id1, id2 [3]
#>      id1   id2     x
#>    <int> <chr> <int>
#>  1     1  x_02    -4
#>  2     1  x_02    -3
#>  3     1  x_02    -2
#>  4     1  x_02    -1
#>  5     1  x_02     1
#>  6     1  x_02     2
#>  7     1  x_02     3
#>  8     1  x_02     4
#>  9     1  x_02     5
#> 10     2  x_02    -2
#> # ... with 11 more rows

简而言之,我想在id1id2 中查找,并找到从x &lt; -2 开始到x &gt; 2 结束的一系列xs(期望的结果下面的 mig 比我在这里描述的更好)。

在某种程度上我认为它是两个过滤器的组合,即我想要这个过滤器,

library(dplyr)
tbl %>% group_by(id1, id2) %>%
   filter( (row_number() == n() & x >  2 ) )
#> # A tibble: 2 x 3
#> # Groups:   id1, id2 [2]
#>     id1   id2     x
#>   <int> <chr> <int>
#> 1     1  x_02     5
#> 2     2  x_03     6

要与这个过滤器结合,

tbl %>% group_by(id1, id2) %>%
   filter( (row_number() == 1 & x < -2 )  )
#> # A tibble: 1 x 3
#> # Groups:   id1, id2 [1]
#>     id1   id2     x
#>   <int> <chr> <int>
#> 1     1  x_02    -4

我想是这样的,但这并没有给我任何数据。

tbl %>% group_by(id1, id2) %>%
   filter( (row_number() == n() & x >  2 ) &
           (row_number() == 1   & x < -2 )  )

为什么不给?

我想要得到/想要的结果

# A tibble: 2 x 3
# Groups:   id1, id2 [1]
    id1   id2     x
  <int> <chr> <int>
1     1  x_02    -4
1     1  x_02     5

【问题讨论】:

  • 您能解释一下为什么您在示例中的条件与您提供的解释不符吗?例如,您说您想在 id1 和 id2 中查找并找到从 > -2 开始并在 -2 相反声明:filter((row_number() == n() & x > 2))。我根本看不出你提到的条件和你的预期结果之间的关系。
  • @StewartRoss,谢谢您的提问。如果我理解正确,调用 row_number() == n() 给我最后一个,n()th,行,row_number() 内,group_by()。在这种情况下是id1id2。然后我将它与条件&amp; 结合起来,即特定的最后一行必须大于该行中的 2,即x &gt; 2。这就是我在数据后的第一次调用中所做的。结果是 id11 1 和 2 和 id2 的调用是 x_02x_03 值 5 和 6。我希望能回答你的问题?如果没有请再问。可以看看我的期望结果。谢谢。
  • 您的代码要求在每个组中保留最后一行且是第一行且 x > 2 且 x
  • 我已经更新了我的文本(就在数据下方)。你说其中一定没有。我不确定我是否同意。对于id1 == 1id2 == x_02 中的情况,有一系列x 值从-4 开始并以5 结束,这正是我想要提取的第一个和最后一个值。这就是我试图在我的期望结果中展示的内容。我想我可能错过了什么?请随时提出您认为可以澄清问题的任何修改。
  • 你试过filter( (row_number() == n() &amp; x &gt; 2 ) | (row_number() == 1 &amp; x &lt; -2 ) )吗?

标签: r filter dplyr conditional relational


【解决方案1】:

当一个组内同时满足这两个条件时,该组应该有 2 行,所以只需再次过滤n() == 2

tbl %>%
  filter((row_number() == n() & x > 2 ) | (row_number() == 1 & x < -2 )) %>%
  filter(n() == 2)

# A tibble: 2 x 3
# Groups: id1, id2 [1]
    # id1 id2       x
  # <int> <chr> <int>
# 1     1 x_02     -4
# 2     1 x_02      5

尝试额外的(见 cmets):

tbl %>%
  filter((row_number() == n() & x > 2 ) | (row_number() == 1 & x < -2 )) %>%
  filter(n() == 2) %>%
  distinct(id1, id2) %>%
  left_join(., tbl, by=c("id1", "id2"))

【讨论】:

  • 请将您的答案放在您的答案中,而不是在 cmets 中。
  • 谢谢。我对它的简单感到惊讶。此外,非常感谢您也回复了附加部分。我设法得到这个解决方案 filter(tbl, any(x &gt; 2) &amp; any(x &lt; -2)) from markus 得到相同的输出。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多