使用方程式计算变量,然后使用生成的值生成新的值

时间:2019-07-18 03:10:36

标签: r loops dplyr tidyverse zoo

很难解释,但我会逐步介绍

假设我有两辆车,一辆接一辆,我有领先车的速度,我想计算两辆车之间的距离,我们可以使用多个方程式来计算距离,了解接下来的汽车的初始速度以及它们之间的距离。

Following_Car_Speed = 13.68490 m/s
Distance = 17.024 m
Lead_Car_Speed = c(13.784896, 13.745834, 13.880556, 13.893577, 13.893577, 13.923959, 
13.945661, 13.919619, 13.897917, 14.002257, 14.002257, 13.980556, 
13.980556, 14.067536, 14.063195, 14.080556, 14.123959, 14.163021, 
14.236806, 14.167188)

Delta_Speed = Lead_Car_Speed[1]-Following_Car_Speed = 13.784896-13.68490 = 0.1

Gap <- 1.554 +  Following_Car_Speed*0.878- (Following_Car_Speed*Delta_Speed)/(2*sqrt(0.8418*0.8150))=
   1.554+ 13.68490*0.878- (13.68490*0.1)/(2*sqrt(0.8418*0.8150) = 12.74325
Acceleration <- 0.8418*(1-(Following_Car_Speed/29.2)^3.52-(Gap/Distance)^2)=0.3116923

现在我已经计算出加速度,所以我必须计算下一辆车的新速度。

Following_Car_Speed <- Following_Car_Speed + Acceleration*0.1 

所以现在我要计算领先车和跟随车之间的新速度差

Delta_Speed <- Lead_Car_Speed[2]-Following_Car_Speed
Distance<- Distance+(Delta_Speed[2]+Delta_Speed[1])/2*0.1

然后继续使用相同的方程式,直到我们得出下一辆车的所有值为止。

使用For循环很容易做到这一点,但是我想获得一种更有效的方法,我尝试使用dplyr,但是很难,但是我没有得到答案。

所以请帮助我。


myfun <- function(list, lcs,lcs2){
        ds <- lcs - list[[1]]
        Distance <- list[[1]]*D_Time - (list[[1]] * ds) / (2*sqrt(M_Acc*Com_Acc))
        if (Distance < 0|is.na(Distance)) {Distance <- 0}
        gap <-  Gap_J + Distance
        acc <- M_Acc * (1 - (list[[1]] / D_Speed)^Beta - (gap / list[[2]])^2)
        fcs_new <- list[[1]] + acc * 0.1
        ds_new <- lcs2- fcs_new
        di_new <- list[[2]]+(ds_new+ds)/2*0.1
        return(list(Speed = fcs_new,Distance = di_new))

} 

Generated_Data <- data %>%group_by(Driver,FileName)%>%
        mutate(Speed_Distance_Calibrated = accumulate2( .init = list(Filling_Speed[1],
                                                                     Filling_Range[1]),.x =  Lead_Veh_Speed_F,.y = Lead_Veh_Speed_F2, myfun)[-1])%>%ungroup()

我已经添加了lead_car_speed的领先者,我也想使用新的距离和新的速度,因此我将其列入列表并将其放入.initla

2 个答案:

答案 0 :(得分:1)

这是使用accumulate软件包中的purrr的简单方法,该软件包是tidyverse的一部分。

首先,我定义一个函数myfun,该函数将更新following_car_speed(fcs)。

myfun <- function(fcs, lcs, di){
  ds <- lcs - fcs
  gap <-  1.554 + fcs*0.878 - fcs * ds / (2*sqrt(0.8418*0.8150))
  acc <- 0.8418 * (1 - (fcs / 29.2)^3.52 - (gap / di)^2)
  fcs_new <- fcs + acc * 0.1

  return(fcs_new)
} 

library(tidyverse)

tibble(lead_car_speed = c(13.784896, 13.745834, 13.880556, 13.893577, 13.893577, 13.923959, 
                          13.945661, 13.919619, 13.897917, 14.002257, 14.002257, 13.980556, 
                          13.980556, 14.067536, 14.063195, 14.080556, 14.123959, 14.163021, 
                          14.236806, 14.167188)) %>%
  mutate(following_car_speed = accumulate(lead_car_speed, myfun, .init = 13.68490, di = 17.024)[-1])^


# A tibble: 20 x 2
   lead_car_speed   following_car_speed
            <dbl> <dbl>
 1           13.8  13.7
 2           13.7  13.7
 3           13.9  13.8
 4           13.9  13.8
 5           13.9  13.8
 6           13.9  13.9
 7           13.9  13.9
 8           13.9  13.9
 9           13.9  13.9
10           14.0  14.0
11           14.0  14.0
12           14.0  14.0
13           14.0  14.0
14           14.1  14.1
15           14.1  14.1
16           14.1  14.1
17           14.1  14.1
18           14.2  14.1
19           14.2  14.2
20           14.2  14.2

如果距离也发生变化,则可以使用accumulate2而不是accumulate

答案 1 :(得分:0)

您的操作取决于迭代或要完成的某种递归(由于可能的NAInf等)-似乎需要forwhile

我的替代版本是将功能分解为更易于扩展的单元和较大示例的单元测试,或者使用其他函数调用进行环绕。

由于某些原因,我假设您的变量Distance是固定的,并且未提供预期的输出,因此我无法完全验证功能。

Following_Car_Speed <- 13.68490
Lead_Car_Speed <- c(13.784896, 13.745834, 13.880556, 13.893577, 13.893577, 
                    13.923959, 13.945661, 13.919619, 13.897917, 14.002257, 
                    14.002257, 13.980556, 13.980556, 14.067536, 14.063195, 
                    14.080556, 14.123959, 14.163021, 14.236806, 14.167188)
Distance <- 17.024

#init
i <- length(Lead_Car_Speed)
Delta_Speed <- c(0.1, vector(mode = "numeric", length = i-1))
Gap <- c(12.74325, vector(mode = "numeric", length = i-1))
Acceleration <- c(0.3116923, vector(mode = "numeric", length = i-1 ))
Following_Car_Speed <- c(Following_Car_Speed, vector(mode="numeric", length = i-1 ))

cal.following.car.speed <- function(Following_Car_Speed, Acceleration){

  #calculate and return current following-car-speed: the i-th following-car-speed
  current.follow.car.speed <- Following_Car_Speed + Acceleration*0.1

  return(current.follow.car.speed)
}                                    

cal.delta.speed <- function(Lead_Car_Speed, following.car.speed){

  #calculate and return current delta speed: the i-th delta speed
  current.delta.speed <- Lead_Car_Speed - following.car.speed

  return(current.delta.speed)
}

cal.gap <- function(Following_Car_Speed, Delta_Speed){

  #calculate and return current gap: the i-th gap
  current.gap <- 1.554 + Following_Car_Speed*0.878 - (Following_Car_Speed*Delta_Speed)/(2*sqrt(0.8418*0.8150))

  return(current.gap)
}

cal.acceleration <- function(Following_Car_Speed, Gap, Distance){

  #calculate and return current acceleration: the i-th acceleration
  current.acceleration <- 0.8418*(1-(Following_Car_Speed/29.2)^3.52-(Gap/Distance)^2)

  return(current.acceleration)
}

#main
counter <- 1

while(counter != i){

  if(counter == 1) {counter = counter + 1} #skip 1st ith as we have init
  else{

    Gap[counter] <- cal.gap(Following_Car_Speed[counter-1], Delta_Speed[counter-1])  

    Acceleration[counter] <- cal.acceleration(Following_Car_Speed[counter-1], Gap[counter-1], Distance)

    Following_Car_Speed[counter] <- cal.following.car.speed(Following_Car_Speed[counter-1], Acceleration[counter])

    Delta_Speed[counter] <- cal.delta.speed(Lead_Car_Speed[counter], Following_Car_Speed[counter])

    counter = counter + 1
  }
}

cbind(Delta_Speed, Gap, Acceleration, Following_Car_Speed)