我需要group_by然后dplyr::filter一个数据帧,以保留基于最小值和最大值的多行

I need to group_by then dplyr::filter a data frame to keep multiple rows based on min and max

提问人:coreyeddy 提问时间:11/18/2023 最后编辑:Tugaycoreyeddy 更新时间:11/22/2023 访问量:45

问:

data1 <- data.frame(PIT = c(20111002, 20111002, 20111002, 20111002, 20111003, 20111003, 20111003, 20111003, 20111003, 20111003, 20111003, 20111003, 20111003, 20111003, 20111003, 20111003,  20111006, 20111006, 20111006, 20111006, 20111006) , rx = c(39,  42, 101, 109,  39,  42, 101, 109, 138, 138, 138, 136, 138, 138, 139, 139, 39, 39, 39, 39 , 42))

data2 <- data.frame(PIT = c(2011102, 2011102, 20111003, 20111003, 20111006, 20111006), rx = c(39, 109, 39, 138, 39, 42))

我需要从 .基本上,每个值有两个:1)第一个最小值和2)第一个最大值或第一个值>110。data2data1PITrxrxrx

我不认为我解释得很好,但我不知所措,不知所措,尝试了各种组合,匹配、第一、切片、最小、最大、过滤器,你能想到的,我已经尝试过了(显然除了解决方案)。另外,是的,我确实group_by并尝试了if_else。

我已经尝试了太多可能的解决方案,无法在此处包含。实际上,我只是花了 15 分钟尝试将代码发布到此消息中,但似乎无法正确格式化它?

R 数据帧 筛选器 group-by slice

评论

0赞 Mark 11/18/2023
“要么是 rx 的第一个最大值,要么是 rx 的第一个值> 110” < - 你如何决定哪一个?
0赞 coreyeddy 11/20/2023
我不知道该如何最好地解释。有时按 PIT 分组时,max(rx) 小于 c(136, 138, 139),所以我需要那一行。有时,max(rx) 是 c(136, 138, 139) 之一,在这种情况下,我需要包含 max 的第一行。事实上,我总是需要第一行,并且只需要包含最小值或最大值的第一行。如果我解释 rx 是沿河的接收器位置,并且我正在寻找最南端 (min(rx)) 和最北端 (max(rx)),这可能是有道理的,但 136、138、139 都是同一个区域,所以我需要包含其中之一的第一行。对不起,言语让我失望了。
0赞 Mark 11/21/2023
也许你可以建立一个更好的样本输入,以及所需的输出,如果单词逃脱了你
0赞 Mark 11/21/2023
我之所以这么说,是因为你以前从未提到过 c(136, 138, 139 这件事
0赞 Mark 11/21/2023
似乎有四种情况:一种是 rx 低于 136,一种是高于 139,一种是 c(136, 138, 139),另一种是缺少数字 137。概述在所有这些情况下您想要什么

答:

1赞 Mark 11/18/2023 #1

一句话:

dplyr::filter(data1, rx %in% c(min(rx), max(rx)) | rx >= 110, .by = PIT)

不确定您希望“rx 的第一个最大值或 rx 的第一个值 > 110”如何工作......但这得到了正确的答案。

评论

0赞 Friede 11/18/2023
错字。更改为 (+1)。data1
0赞 coreyeddy 11/20/2023
谢谢。这似乎几乎有效,但我为每个 PIT 获得多行,我只需要两行,第一个最小值和第一个最大值(或包含 136、138、139 的第一行)。我该如何服用第一个?我尝试过first(),match(),head(),但它们不起作用。
0赞 coreyeddy 11/22/2023 #2

看起来这有效。它可能不是最好或最精简的,但它有效。

min <- data1 %>% 
  group_by(PIT) %>%
  dplyr::filter(rx==min(rx)) %>%
  slice(1)

max1 <- data1 %>% 
  group_by(PIT) %>%
  dplyr::filter(max(rx)<110 & rx == max(rx)) %>%
  slice(1)

max2 <- data1 %>% 
  group_by(PIT) %>%
  dplyr::filter(rx > 110) %>%
  slice(1)

data2 <- dplyr::full_join(min, max1) %>%
  dplyr::full_join(max2) %>% arrange(PIT,Presence)