gpt4 book ai didi

R中有条件的滚动计算

转载 作者:行者123 更新时间:2023-12-01 09:08:39 26 4
gpt4 key购买 nike

我有一个数据表,例如:

 CurrOdo        Lat            NextLat       PrevODO        NextOdo
2.62 30.01115868 30.01115868
5.19 30.01116407 30.01116407
7.61 30.01116919 30.01116919
18.82 30.01119282 7.61 19.06
19.06 30.01119282 30.01119282
19.35 30.01119339 30.01119339
20.54 30.01122998 19.35 81.5
20.81 30.01122998 20.54 81.5
37.38 30.01122998 20.81 81.5
81.5 30.01132238 30.01132238

atable<-data.table(odo = c(2.62,5.19,7.61,18.82,19.06,19.35,20.54,20.81, 37.38,81.5 ),
Lat = c(30.01115868,30.01116407,30.01116919,NA,30.01119282,30.01119339,NA,NA, NA, 30.01132238),
NextLat=c(30.01115868,30.01116407,30.01116919, 30.01119282, 30.01119282,30.01119339,
30.01122998,30.01122998,30.01122998,30.01122998 ),
PrevLat=c(NA,NA,NA, NA, NA,NA, NA,NA,NA,NA ),
PrevODO=c(NA,NA,NA, 7.61, NA,NA, 19.35,20.54,20.81,NA ),
NextOdo=c(NA,NA,NA, 19.06, NA,NA, 81.5,81.5,81.5,NA ))

Lat 值是基于此公式的滚动计算:

纬度:(NextLat- PrevLat) * ((CurrODO - PrevODO)/(NextODO - PrevODO)) + PrevLat

如何计算 Lat 的示例

Row CurrODO 18.82:   (30.01119282- 30.01116919) * (( 18.82 - 7.61) / (19.06 - 7.61)) + 30.01116919
Row CurrODO 20.54: (30.01122998- 30.01119339) * (( 20.54 - 19.35) / (81.5 - 19.35)) + 30.01119339
Row CurrODO 20.81: (30.01122998- Lat calc result from 20.54 row) * ((20.81 - 20.54) / (81.5 - 20.54)) + Lat calc result from 20.54 row
Row CurrODO 37.38: (30.01122998- Lat calc result from 20.81 row) * (( 37.38 - 20.81) / (81.5 - 20.81)) + Lat calc result from 20.81 row

最终结果是:

CurrOdo     Lat             NextLat         PrevODO     NextOdo
2.62 30.01115868 30.01115868
5.19 30.01116407 30.01116407
7.61 30.01116919 30.01116919
18.82 30.0111923247 30.01119282 7.61 19.06
19.06 30.01119282 30.01119282
19.35 30.01119339 30.01119339
20.54 30.0111940906 30.01122998 19.35 81.5
20.81 30.0111942496 30.01122998 20.54 81.5
37.38 30.0112040049 30.01122998 20.81 81.5
81.5 30.01132238 30.01132238

我目前正在 SQL Server 中循环运行它,但这需要很长时间。我也可以将它与 R 放在一个循环中,但是它在大型数据集上表现不佳。我已经坚持了好几天了,所以感谢您的帮助!

最佳答案

我的回答涉及一个重复循环,虽然你说“没有循环”,但我没有看到任何其他方式(当然可能有,这是 R ;-))。< br/>虽然循环应该执行得非常快,但在我的系统上,它需要大约一秒钟的时间来填充 1000 万行的 NA(参见基准测试)。

Lat 的输出与问题中所需的输出匹配。

旁注:
如果您的第一个 Lat 值为 NA,您可能会遇到问题。
因为 PrevLat 在第一行总是 NA,所以 Lat 的第一行 NA 永远不会被重新计算,循环也永远不会中断。
您(当然)可以在循环中构建逃生路线/中断以防止这种情况发生。我保留了这一点,以保持示例的可读性和简短性。

repeat{
#until there are no more NA in Lat
if( sum( is.na( atable$Lat ) ) == 0 ){
break
}
#(re)calculate PrevLat
atable[, PrevLat := shift( Lat, 1, type = "lag" ) ]
#calculate Lat when PrevLat is known, but Lat is not
atable[ is.na( Lat ) & !is.na( PrevLat ),
Lat := (NextLat-PrevLat)*((odo-PrevODO)/(NextOdo-PrevODO))+PrevLat ]
}

# odo Lat NextLat PrevLat PrevODO NextOdo
# 1: 2.62 30.0111586800 30.01115868 NA NA NA
# 2: 5.19 30.0111640700 30.01116407 30.0111586800 NA NA
# 3: 7.61 30.0111691900 30.01116919 30.0111640700 NA NA
# 4: 18.82 30.0111923247 30.01119282 30.0111691900 7.61 19.06
# 5: 19.06 30.0111928200 30.01119282 30.0111923247 NA NA
# 6: 19.35 30.0111933900 30.01119339 30.0111928200 NA NA
# 7: 20.54 30.0111940906 30.01122998 30.0111933900 19.35 81.50
# 8: 20.81 30.0111942496 30.01122998 30.0111940906 20.54 81.50
# 9: 37.38 30.0112040049 30.01122998 30.0111942496 20.81 81.50
# 10: 81.50 30.0113223800 30.01122998 NA NA NA

基准

在 10M 行的 data.table 上(您的 atable 重复了 1M 次);
在我的系统上(+/- 6 岁的 i5,内存为 16Gb),循环大约需要一秒钟来计算每个纬度的值。

dt <- atable[rep(atable[, .I], 1000000)]

system.time(
repeat{
#until there are no more NA in Lat
if( sum( is.na( dt$Lat ) ) == 0 ){
break
}
#(re)calculate PrevLat
dt[, PrevLat := shift( Lat, 1, type = "lag" ) ]
#calculate Lat when PrevLat is known
dt[ is.na( Lat ) & !is.na( PrevLat ),
Lat := (NextLat- PrevLat ) * ((odo - PrevODO) / (NextOdo - PrevODO)) + PrevLat ]
}
)

# user system elapsed
# 0.90 0.35 1.08

session 信息

R version 3.6.1 (2019-07-05)   
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 18362)

other attached packages: [1] data.table_1.12.4

update::代码解释

代码的作用:

  1. 它用上一行的 Lat 值填充 Prevlat
  2. 它标识所有 LatNA PrevLat 具有值(即 不适用)
  3. 对于在第 2 步中识别的所有行,根据您提供的函数计算 Lat 的值

重复步骤1到3,直到校验is.na(atable$Lat)的和等于0,当满足这个条件时,就不再有NA-Lat 列中的值...因此我们可以使用 break 退出 repeat 循环。

关于R中有条件的滚动计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58562719/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com