Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 按顺序分组,然后在列中查找最小值_R_Aggregate_Tidyverse - Fatal编程技术网

R 按顺序分组,然后在列中查找最小值

R 按顺序分组,然后在列中查找最小值,r,aggregate,tidyverse,R,Aggregate,Tidyverse,我有一个数据集,其他大多数列都有date、sequence和low列,请参见下面的df。 在序列列中,从1到-9的序列被视为一个区块或一个完整周期 数据集有几个完整的块/周期和部分完成的块/周期,eg:1-to-4 这就是我试图解决的问题: 移除部分完成的循环,然后将整个循环分组(请参见df1) 对于每个块/周期(即从1到9的序列),我想找到 在低谷发生的当天,街区的低谷一直持续 如果存在两个相同值但日期不同的低点,则 它只能输出最新日期(参见输出中的第三个块) 库(lubridate) 图书馆

我有一个数据集,其他大多数列都有
date、sequence和low
列,请参见下面的
df
。 在
序列
列中,从
1到-9的序列被视为一个区块或一个完整周期
数据集有几个完整的块/周期和部分完成的块/周期,
eg:1-to-4

这就是我试图解决的问题:

  • 移除部分完成的循环,然后将整个循环分组(请参见
    df1
  • 对于每个块/周期(即从1到9的序列),我想找到 在低谷发生的当天,街区的低谷一直持续
  • 如果存在两个相同值但日期不同的低点,则 它只能输出最新日期(参见输出中的第三个块)

    库(lubridate)
    图书馆(tidyverse)
    ###样本数据
    df%变异(日期=dmy(日期))
    
    按循环/块分组的数据
    df1%突变(日期=dmy(日期))
    
  • 我追求的最终输出

      df_final <- data.frame(stringsAsFactors=FALSE,
             date = c("4/01/2019", "14/01/2019", "3/02/2019"),
              low = c(18, 1, 9)) %>% mutate(date = dmy(date))
    
    df_最终%变异(日期=dmy(日期))
    
    有什么想法吗?

    另外,我在格式化这个问题时遇到了一些问题,因此不整洁

    我们通过取序列为1的累积和来创建分组变量,然后
    仅过滤具有9个元素的组,并
    切片
    之后“low”最小的行安排
    desc
    结束顺序中对“date”进行排序,以处理“low”est值存在关联的情况

    df %>% 
       group_by(group = cumsum(sequence == 1)) %>% 
       filter(n() == 9) %>% 
       select(date, low) %>%
       arrange(desc(date)) %>%
       slice(which.min(low)) %>%
       ungroup %>%
       select(-group)
    # A tibble: 3 x 2
    #  date         low
    #  <date>     <dbl>
    #1 2019-01-04    18
    #2 2019-01-14     1
    #3 2019-02-03     9
    

    另一种可能性是:

    df %>%
     group_by(group = cumsum(sequence == 1), rleid = with(rle(group), rep(seq_along(lengths), lengths))) %>%
     filter(all(c(1:9) %in% sequence)) %>%
     slice(which.min(rank(low, ties.method = "last"))) %>%
     ungroup() %>%
     select(-group, -rleid)
    
      date       sequence   low
      <date>        <dbl> <dbl>
    1 2019-01-04        4    18
    2 2019-01-14        1     1
    3 2019-02-03        8     9
    
    df%>%
    分组依据(组=总和(序列==1),rleid=带(rle(组),代表(沿(长度)的顺序),长度))%>%
    过滤器(所有(c(1:9)%in%序列))%>%
    切片(which.min(秩(low,ties.method=“last”))%>%
    解组()%>%
    选择(-group,-rleid)
    日期顺序低
    1 2019-01-04        4    18
    2 2019-01-14        1     1
    3 2019-02-03        8     9
    

    在这里,它首先基于累积和创建“序列”==1的累积和和
    rleid()
    -样变量,然后根据这两个变量执行分组。其次,它消除了序列不包含所有九个值的情况。最后,在ties返回最后一个最小值的情况下,它返回每个组的最小值(您可以通过参数
    ties.method
    对其进行修改)。

    这在基本R中也是可能的。不过可能有点mapsy

    w <- which(df$sequence == 1)
    w <- w[sapply(w, function(x) df$sequence[x + 8] == 9 & sum(df$sequence[x:(x + 8)]) == 45)]
    do.call(rbind, Map(function(x) x[which.min(x$low), ], 
                       Map(function(s) df[s, ], Map(seq, w, l=9))))
    #          date sequence low
    # 4  2019-01-04        4  18
    # 14 2019-01-14        1   1
    # 32 2019-02-01        6   9
    

    @头足类动物你能检查输出吗最后一个值9应该有日期
    2019-02-03
    我选择了
    Akrun
    ,因为他的代码对我来说更容易理解。但愿我能不止一次地投票支持你的答案!
    library(data.table)
    setDT(df)[, .SD[.N == 9], .(group = cumsum(sequence == 1))
              ][order(-date), .SD[which.min(low)], group]
    
    df %>%
     group_by(group = cumsum(sequence == 1), rleid = with(rle(group), rep(seq_along(lengths), lengths))) %>%
     filter(all(c(1:9) %in% sequence)) %>%
     slice(which.min(rank(low, ties.method = "last"))) %>%
     ungroup() %>%
     select(-group, -rleid)
    
      date       sequence   low
      <date>        <dbl> <dbl>
    1 2019-01-04        4    18
    2 2019-01-14        1     1
    3 2019-02-03        8     9
    
    w <- which(df$sequence == 1)
    w <- w[sapply(w, function(x) df$sequence[x + 8] == 9 & sum(df$sequence[x:(x + 8)]) == 45)]
    do.call(rbind, Map(function(x) x[which.min(x$low), ], 
                       Map(function(s) df[s, ], Map(seq, w, l=9))))
    #          date sequence low
    # 4  2019-01-04        4  18
    # 14 2019-01-14        1   1
    # 32 2019-02-01        6   9
    
    df <- structure(list(date = structure(c(17897, 17898, 17899, 17900, 
    17901, 17902, 17903, 17904, 17905, 17906, 17907, 17908, 17909, 
    17910, 17911, 17912, 17913, 17914, 17915, 17916, 17917, 17918, 
    17919, 17920, 17921, 17922, 17923, 17924, 17925, 17926, 17927, 
    17928, 17929, 17930, 17931), class = "Date"), sequence = c(1, 
    2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 9, 
    1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 9), low = c(96, 81, 43, 18, 
    43, 65, 48, 90, 69, 50, 41, 73, 1, 1, 7, 49, 16, 79, 2, 74, 8, 
    88, 56, 57, 66, 29, 79, 51, 52, 47, 42, 9, 41, 9, 50)), row.names = c(NA, 
    -35L), class = "data.frame")