当前位置: 首页 > 知识库问答 >
问题:

使用rle和for循环超过阈值的最长连续周期

焦正德
2023-03-14

我有一个月的四年的流量数据,我正试图找出如何在四年中的每一年提取出某个阈值或以上的最长连续时间段。在下面的示例中,阈值是4。我想尝试使用for循环或可能的apply函数之一来实现这一点,但我不确定如何实现。

这是我的示例数据框架:

year <- c(rep(2009,31), rep(2010, 31), rep(2011, 31), rep(2012, 31))
day<-c(rep(seq(1:31),4))
discharge <- c(4,4,4,5,6,5,4,8,4,5,3,8,8,8,8,8,8,8,1,2,2,8,8,8,8,8,8,8,8,8,4,4,4,5,6,3,1,1,3,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,9,10,3,3,3,3,3,3,1,1,3,8,8,8,8,8,8,8,8,8,1,2,2,8,8,3,8,8,8,8,8,8,4,4,4,5,6,3,1,1,3,3,3,3,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,9,3)

df<-data.frame(cbind(year, day, discharge))
df$threshold<-ifelse(discharge>=4,1,0)

在此示例中,如果放电等于或高于阈值,则阈值列编码为 1,如果不是,则编码为 0。我能够使用以下代码部分获得一年(以下示例中的 2009 年)的所需输出:

rl2009<-with(subset(df,year==2009),rle(threshold))
cs2009 <- cumsum(rl2009$lengths)
index2009<-cbind(cs2009[rl2009$values == 1] - rl2009$length[rl2009$values == 1] + 1,
cs2009[rl2009$values == 1])
df2009<-data.frame(index2009)
df2009 #ouput all periods when flow is above threshold
df2009$X3<-df2009$X2-df2009$X1+1

max2009<-df2009[which.max(df2009$X3),]
max2009 #output the first and longest period when flow is above threshold

对于2009年,有三个时间段的流量等于或超过4,但是选择从第1天到第10天的时间段,因为这是高于阈值的最长时间段的第一个。X1代表时间段的开始,X2代表时间段的结束,X3代表时间段中的天数。如果有多个相同天数的周期,我希望选择第一个周期。

我四年的预期产出如下:

year   X1  X2  X3
2009    1  10  10
2010    9  31  23
2011   10  18   9
2012   12  30  19

实际的数据包括更多的年份和许多流,因此不可能逐年进行。如果有人对如何实现这一目标有任何想法,我们将不胜感激。谢谢

共有1个答案

姬选
2023-03-14

简单地说,使用定义的函数(例如threshold_find)概括您的流程,并将每年子集的数据帧传递到其中,这些数据帧可以通过以下方式处理

作为< code>tapply的面向对象包装器,< code>by按一个或多个因子(即年份)对数据帧进行切片,并返回定义的函数输出的任何对象的列表,这里是最大数据帧。最后,< code>do.call() row将< code>by列表中的所有数据帧绑定到一个数据帧中。

threshold_find <- function(df) {
  rl <- with(df, rle(threshold))      
  cs <- cumsum(rl$lengths)

  index <- cbind(cs[rl$values == 1] - rl$length[rl$values == 1] + 1,
                 cs[rl$values == 1])
  df <- data.frame(index)
  df$X3 <- df$X2 - df$X1+1

  max <- df[which.max(df$X3),]
  max      
}

finaldf <- do.call(rbind, by(df, df$year, FUN=threshold_find))

finaldf
#      X1 X2 X3
# 2009  1 10 10
# 2010  9 31 23
# 2011 10 18  9
# 2012 12 30 19
 类似资料:
  • DB_示例我正在探索数据库的自动化测试,并努力在表中找到空值。 我想测试: > 如果EID2= 有null值,我得到以下错误:不能调用String.startswith(String),因为java.util.Map.get(对象)的返回值为null。 我的第一个值总是空的,所以我从计数器1开始循环,这解决了这个问题,但是我的表中的EID和CID中都有空值。如果不满足条件(即值为null),测试失

  • 我需要找到我的数据连续几天达到阈值的位置。我正在寻找超过阈值的4个连续观察值。我想返回符合这些标准的系列的第一个观察值的位置。 下面是一个数据集示例: 我想要平均符合标准的日期(平均 在这种情况下,我可以将第一种情况下的< code>TRUE作为答案,但如果第二种、第三种或第四种情况不是< code>TRUE,这将不起作用 我需要条件为的第一个日期: 以及该系列中第一个观察的位置: 我已经找到了相

  • 当我查看注册表仪表板时,当结束时,我会看到以下警告消息: 当我查看代码时,测试始终为true 为什么是默认配置,它似乎怪异,因为它不断地产生一个警告! 如果有谁能给我一个解释。我想我错过了什么…

  • 本文向大家介绍使用JavaScript中的while循环查找最长的连续数字子数组,包括了使用JavaScript中的while循环查找最长的连续数字子数组的使用技巧和注意事项,需要的朋友参考一下 我们需要编写一个带有while语句的函数,该函数确定正整数数组中最大的连续子数组的长度。 例如- 如果输入数组是- 那么输出应该是- 如果输入数组是- 那么输出应该是- 因此,让我们为该函数编写代码- 示

  • 关于如何使用for和while循环将值列表到空列表,我有两种方法。 例1。创建一个函数,该函数接受用户的输入,并在列表中列出十进制正值,直到用户插入负值。然后清单结束,最后一个值应该是这个负值。输出应该是什么样子的: 在列表中添加数字:1.5在列表中添加数字:5.2在列表中添加数字:6在列表中添加数字:-2列表:[1.5,5.2,6.0,-2.0] 我的选拔赛没成功 示例2关于将for循环和ran

  • 我有数据,我想应用滚动函数来检测哪个点的值大于特定阈值。 我想要的是找到下一个2个值高于某个阈值(例如30)的行。这将产生以下结果: 我有一个大的数据集(几百万行),所以我试图找到一个有效的解决方案。也许使用?由reprex包(v0.2.1)在2019-02-26创建