根据输入值在不同函数之间迭代

问题描述 投票:0回答:1

我有室外温度数据

df1 <- read.table(text = "DT   temp.out
'2023-01-18 00:00:00'   6.8
'2023-02-18 23:00:00'   1.5
'2023-03-04 00:00:00'   2.6
'2023-04-20 03:00:00'   -5.0
'2023-06-21 05:00:00'   11.9
'2023-08-10 19:00:00'   6.2
'2023-08-21 23:00:00'   -2.8
'2023-09-19 01:00:00'   5.7
'2023-11-3 07:00:00'    9.1
'2023-12-21 13:00:00'   -19.8", header = TRUE) %>% 
  mutate (DT = as.POSIXct(DT))

对于每个观察结果,我确定 COP 指标的值。这取决于 tzas 的价值。由于(当前)我有两个函数根据 tzas(60 和 30)描述 COP 值,因此我使用比例(线性关系)计算中间值的值。

COP.licz <- function(tout) {
  tzas = -0.78 * tout + 35.789
  COP.60 = 0.026 * tout + 2.937
  COP.30 = 0.0368 * tout + 3.46
  (COP.30 - COP.60) / (60 - 30) * (tzas - 30) + COP.30
}


df1 <- df1 %>% 
  mutate (
    tzas = -0.78 * temp.out + 35.789,
    COP.chw = COP.licz (temp.out)
  )

我还剩下结果

> df1
                    DT temp.out  COP.chw
1  2023-01-18 00:00:00      6.8 3.719882
2  2023-02-18 23:00:00      1.5 3.598219
3  2023-03-04 00:00:00      2.6 3.624767
4  2023-04-20 03:00:00     -5.0 3.427471
5  2023-06-21 05:00:00     11.9 3.822061
6  2023-08-10 19:00:00      6.2 3.706901
7  2023-08-21 23:00:00     -2.8 3.487919
8  2023-09-19 01:00:00      5.7 3.695929
9  2023-11-03 07:00:00      9.1 3.767771
10 2023-12-21 13:00:00    -19.8 2.950173
> 

在下一个版本中,我有几个(也许更多)COP 函数(tzas):COP.60、COP.55、COP.50、COP.30。 我想在 COP.chw 计算中使用这些附加函数 例如: temp.out 为 -19.8,因此 tzas 为 51.233 COP.chw 将根据 COP.50 和 COP.60 值之间的比例计算

使用

if
case_when
似乎是一个非常有力的解决方案。

依赖项/函数示例

COP.60 = 0.026 * tout + 2.937
COP.55 = 0.029 * tout + 2.907
COP.50 = 0.0315 * tout + 3.001
COP.30 = 0.0368 * tout + 3.46
r tidyverse
1个回答
0
投票

您可以使用以下结构;请注意,对于小于 30 的 tzas 值,您需要定义另一个段,因为它当前返回 null,因为没有匹配的混合。

df1 <- read.table(text = "DT   temp.out
'2023-01-18 00:00:00'   6.8
'2023-02-18 23:00:00'   1.5
'2023-03-04 00:00:00'   2.6
'2023-04-20 03:00:00'   -5.0
'2023-06-21 05:00:00'   11.9
'2023-08-10 19:00:00'   6.2
'2023-08-21 23:00:00'   -2.8
'2023-09-19 01:00:00'   5.7
'2023-11-3 07:00:00'    9.1
'2023-12-21 13:00:00'   -19.8", header = TRUE) %>% 
  mutate (DT = as.POSIXct(DT))

blend <- function(tzas,low_cut,low_val,high_cut,high_val){
  (low_val - high_val) / (high_cut-low_cut) * (tzas - low_cut) + low_val
}

COP.licz_0 <- function(tout) {
  tzas = -0.78 * tout + 35.789
  
  COP.30 = 0.0368 * tout + 3.46
  COP.50 = 0.0315 * tout + 3.001
  COP.55 = 0.029 * tout + 2.907
  COP.60 = 0.026 * tout + 2.937

  which_cut <- as.integer(cut(tzas,breaks = c(30,50,55,60)))
  r <- switch(which_cut,
         blend(tzas,30,COP.30,50,COP.50),
         blend(tzas,50,COP.50,55,COP.55),
         blend(tzas,55,COP.55,60,COP.60)
          )
r
}
COP.licz <- Vectorize(COP.licz_0,vectorize.args = "tout")


df1 <- df1 %>% 
  mutate (
    tzas = -0.78 * temp.out + 35.789,
    COP.chw1 = COP.licz (temp.out)
  )
© www.soinside.com 2019 - 2024. All rights reserved.