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")