我有一个数据框,它代表了一条河流两年的每日温度时间序列.对于这条河,我想知道一年中的哪一天(doy):

  1. 持续温度大于或等于10度
  • 持续是指一年中的最高温度不再低于10到after,例如在秋季或冬季
  1. 气温持续低于或等于10度
  • 持续是指在下一年之前不会再出现10以上的峰值

当我试图计算2时,我遇到了错误,因为有多个TRUE个答案可供代码 Select .我想知道我如何才能让代码与前TRUE个答案,如果有多个TRUE个答案.

示例数据集

library(ggplot2)
library(lubridate)
library(dplyr)
library(dataRetrieval)

siteNumber <- "01417500"
parameterCd <- "00010" # water temperature
statCd <- "00003" # mean
startDate <- "2015-01-01"
endDate <- "2016-12-31"

dat <- readNWISdv(siteNumber, parameterCd, startDate, endDate, statCd=statCd)
dat <- dat[,c(2:4)]
colnames(dat)[3] <- "temperature"

# Visually inspect the time series
ggplot(data = dat, aes(x = Date, y = temperature)) +
  geom_point() +
  theme_bw()

%1&amp;%2的代码,其中%2有问题,因为有多个TRUE语句可供 Select

dat %>%
  mutate(year = year(Date),
         doy = yday(Date)) %>%
  group_by(year) %>%
  mutate(gt_10 = temperature >= 10, # greater than or equal to 10 degrees
         lt_10 = temperature <= 10, # less than or equal to 10 degrees
         peak_doy = doy[which.max(temperature)], # what doy is max temperature
         below_peak = doy < peak_doy, # is the observed doy less than the peak temperature doy
         after_peak = doy > peak_doy, # is the observed doy greater than the peak temperature doy
         test_above = ave(gt_10, cumsum(!gt_10), FUN = cumsum), # counts number of days above 10 degree threshold
         test_below = ave(lt_10, cumsum(!lt_10), FUN = cumsum)) %>% # counts number of days below 10 degree threshold
  summarise(first_above_10_sustained = doy[below_peak == T & test_above == 14]-13, # answer to 1 
            first_below_10_sustained = doy[after_peak == T & test_below == 14]-13) # answer to 2
  • 为了回答2,代码查看当温度为年最高温度after(即,after_peak == T)and时,温度已连续14天低于10阈值(即,test_below == 14)的那些时间.test_below == 14是错误所在,因为发生这种情况的次数很多.是的,您可以将连续天数的阈值更改为某个值,但这不是重点.如果有多个TRUE个答案,我如何获得接受第一个TRUE答案的代码?

我的答案是similar SO question here,但我的答案只有在没有多个TRUE个答案可供 Select 的情况下才有效.

推荐答案

这里有几个我会用到的技巧:

  1. 创建一个列,用于指定温度是高于还是低于10度.
  2. 获取该列的rleid,它将对高于或低于10度阈值的所有连续日期进行分组.
  3. 找出每年的最高气温,并将其存储在一列中.
  4. 根据您定义,包含最高温度的rleid将是该年气温保持10度的日期
  5. 对最低气温做同样的事情,但在计算年份时减go 6个月,以在计算该年的最低气温时进行分组.这不会对最终结果产生影响,但可以计算冬季的最低温度:
df <- dat %>%
  mutate(year = year(Date)) %>%
  group_by(year) %>%
  mutate(max_temp = max(temperature)) %>%
  ungroup() %>%
  mutate(above_ten = temperature >= 10,
         run = factor(data.table::rleid(above_ten))) %>%
  group_by(run) %>%
  mutate(sustained_hi = max(temperature) == max(max_temp)) %>%
  ungroup() %>%
  mutate(year = year(Date - months(6))) %>%
  group_by(year) %>%
  mutate(min_temp = min(temperature)) %>%
  group_by(run) %>%
  mutate(sustained_lo = min(temperature) == min(min_temp)) %>%
  mutate(group = ifelse(sustained_hi, 'High', 
                        ifelse(sustained_lo, 'Low', 
                               'Unsustained'))) %>%
  select(site_no, Date, temperature, group, run)

这将导致:

df
#> # A tibble: 731 x 5
#> # Groups:   run [27]
#>    site_no  Date       temperature group run  
#>    <chr>    <date>           <dbl> <chr> <fct>
#>  1 01417500 2015-01-01         0.7 Low   1    
#>  2 01417500 2015-01-02         1.1 Low   1    
#>  3 01417500 2015-01-03         1   Low   1    
#>  4 01417500 2015-01-04         2.5 Low   1    
#>  5 01417500 2015-01-05         2   Low   1    
#>  6 01417500 2015-01-06         0.3 Low   1    
#>  7 01417500 2015-01-07         0.2 Low   1    
#>  8 01417500 2015-01-08         0.2 Low   1    
#>  9 01417500 2015-01-09         0.3 Low   1    
#> 10 01417500 2015-01-10         0.3 Low   1    
#> # ... with 721 more rows
#> # i Use `print(n = ...)` to see more rows

而我们可以通过这样的绘制来看到结果:

ggplot(df, aes(x = Date, y = temperature, color = group)) +
  geom_point() +
  scale_color_manual(limits = c('High', 'Unsustained', 'Low'),
                     values = c('orange', 'gray', 'steelblue')) +
  theme_bw()

enter image description here

我们可以通过以下操作获得持续高温/低温的开始和结束日期的漂亮的小数据框:

df %>% 
  filter(group != 'Unsustained') %>%
  group_by(run) %>%
  summarize(Date = c(first(Date), last(Date)),
            Event = paste('Sustained', first(group), c('Start', 'End'))) %>%
  ungroup() %>%
  select(-run)
#> # A tibble: 10 x 2
#>    Date       Event               
#>    <date>     <chr>               
#>  1 2015-01-01 Sustained Low Start 
#>  2 2015-04-28 Sustained Low End   
#>  3 2015-04-29 Sustained High Start
#>  4 2015-07-16 Sustained High End  
#>  5 2015-11-08 Sustained Low Start 
#>  6 2016-03-31 Sustained Low End   
#>  7 2016-05-18 Sustained High Start
#>  8 2016-10-09 Sustained High End  
#>  9 2016-10-23 Sustained Low Start 
#> 10 2016-12-31 Sustained Low End 

R相关问答推荐

在值和NA的行顺序中寻找中断模式

判断字符串中数字的连续性

pickerInput用于显示一条或多条geom_hline,这些线在图中具有不同 colored颜色

过滤器数据.基于两列的帧行和R中的外部向量

用相同方法得到不同函数的ROC最优截断值

当月份额减go 当月份额

从BRM预测价值

如何对2个列表元素的所有组合进行操作?

如何删除最后一个可操作对象

根据约束随机填充向量的元素

R -基线图-图形周围的阴影区域

数据集上的R循环和存储模型系数

如何在Quarto中使用美人鱼图表中的标记来加粗文本

R try Catch in the loop-跳过缺少的值并创建一个DF,显示跳过的内容

R:使用ApexCharge更改标签在饼图中的位置

附加中缀操作符

如何使用list_rind在列表中保留已命名但不包含第0行的记录?

在直方图中显示两个变量

在R中,有没有什么方法可以根据一列中的多个值来过滤行?

如何在分组蜂群小区中正确定位标签