【问题标题】:Filter all values before max value using dplyr使用 dplyr 过滤最大值之前的所有值
【发布时间】:2016-07-12 02:22:28
【问题描述】:

我对如何正确执行以下操作感到相当困惑。我知道这可能很简单,但我无法弄清楚。

假设我有一个仪器收集的数据,该仪器在水中升高和降低。作为数据的补充,进行深度读数。假设我只对down路上的数据感兴趣,并想过滤掉所有向上的数据。更明确地说,我想过滤 depth 的最低值之前的深度读数。一个小问题是,数据通常有几个深度值会在继续下降到最深点之前略​​微上升。所以这不是一个纯粹的上升/下降问题。理想情况下使用dplyr 方法(或与dplyr 配合良好的方法),因为我在数据中有组。这是一些虚拟数据:

library(dplyr)

df1 <- data.frame(depth=c(1:6,5,7:10,10.5:1), x=rnorm(21), Group="x")
df2 <- data.frame(depth=c(1:6,5,7:10,10.5:1), x=rnorm(21), Group="y")
df <- rbind(df1, df2)

我总是被卡住,因为我很容易找到最深的价值:

df %>% mutate(depth==max(depth))

我还可以找到(使用@Marc 的答案)一组的深度:

df %>%
  filter(Group=="x") %>%
  add_rownames() %>%
  filter(rowname %in% c(seq(which.max(depth))))

但是,当我尝试添加 group_by 语句时,我仍然只能从第一组获得所需的结果:

df %>%
  add_rownames() %>%
  group_by(Group) %>%
  filter(rowname %in% c(seq(which.max(depth))))

我没想到group_by 可以使用过滤器,但我不知道如何在不使用过滤器的情况下子为行名。这里有什么想法吗?

【问题讨论】:

  • @Psidom - 正如我上面所说,严格来说,这不是我需要匹配的升序/降序模式。
  • @Marc 的回答能满足你的需要吗?
  • @Psidom 不完全是。我还没有完全弄清楚如何在类似dplyr 的方法中应用它。
  • 一定要使用dplyr吗?马克的回答哪一部分不正确?
  • 我尽量让我的例子简单,但我的实际应用是按组做事情练习。因此,在一个因子指定的组中找到高于最低点的所有值。所以马克的回答并不完全不正确。我只是不知道如何在dplyr 中应用行号方法,以便可以使用group_by

标签: r dplyr


【解决方案1】:

另一种方法

library(dplyr)
df %>% group_by(Group) %>% filter(between(row_number(),1,which.max(depth)))

【讨论】:

  • 好答案。看来row_number()这里是分组的。
  • +1 这个答案有效,但请注意,这里的过滤器功能很容易受到您对数据的排序方式的影响,因为它适用于 row_number。避免问题的一个简单预防步骤可能是对指示测量时间的变量的数据进行排序(不包括在 OP 的虚拟数据中)。
【解决方案2】:

这行得通:

df[seq(which.max(df$depth)),]

【讨论】:

    【解决方案3】:

    似乎没有针对该问题提出dplyr 解决方案,但data.table 替代方案有效:

    library(data.table)
    setDT(df)[, head(.SD, which.max(depth)), by = Group]  
    # say the factor is some grouping variable you are trying to apply
    
        Group depth           x
     1:     x   1.0 -0.22907469
     2:     x   2.0  0.15284187
     3:     x   3.0  1.99289070
     4:     x   4.0 -0.80802497
     5:     x   5.0  0.41455226
     6:     x   6.0  0.39673474
     7:     x   5.0 -0.35179347
     8:     x   7.0 -0.18892176
     9:     x   8.0  2.97448709
    10:     x   9.0 -0.14464747
    11:     x  10.0  0.99434061
    12:     x  10.5 -0.64831649
    13:     y   1.0  1.10262757
    14:     y   2.0 -0.64630288
    15:     y   3.0  0.43909555
    16:     y   4.0 -0.00575027
    17:     y   5.0 -0.81374528
    18:     y   6.0 -0.45948930
    19:     y   5.0  0.03333462
    20:     y   7.0  0.31111807
    21:     y   8.0  1.64502251
    22:     y   9.0  0.97451275
    23:     y  10.0  1.12403518
    24:     y  10.5  1.21710311
        Group depth           x
    

    坚持dplyr,您可以创建一个新的id变量来单独标记每个组的行,然后根据which.max进行过滤:

    df %>% group_by(Group) %>% mutate(id = seq_len(n())) %>% filter(id <= which.max(depth))
    

    【讨论】:

    • 我已经修改了我的问题。多亏了你和 Marc,我离得更近了一点,但我还没有到。
    • 为答案添加了dplyr 解决方案。问题是当您使用dplyr 添加行名时,它不是按组添加的,因此该解决方案不起作用。您可以为每个组单独添加一个 id 变量,然后根据它进行子集。
    猜你喜欢
    • 2022-06-11
    • 2017-01-09
    • 2018-11-17
    • 1970-01-01
    • 1970-01-01
    • 2017-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多