R中带条件的滚动计算

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

我有一个数据表,例如:

 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

如何计算纬度的示例

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
1个回答
0
投票
我很乐意被R专家纠正,但是我还没有真正见过简单的方法来累加向前累积值而不会像您所做的那样循环。

但是我想如果您安装Rcpp和任何相关的用具,您可以执行以下操作:

src <- "NumericVector fill_lat_na(NumericMatrix v){ NumericVector ret(v.nrow()); for(int i=0; i < v.nrow(); ++i){ ret[i] = v(i, 1); if(NumericVector::is_na(ret[i])) { ret[i] = (v(i, 2) - ret[i-1]) * ((v(i, 0) - v(i, 4)) / (v(i, 5) - v(i, 4))) + ret[i-1] ; } } return(ret); } " Rcpp::cppFunction(src)

这将为您提供一个函数fill_lat_na(),您可以用R方式调用它:

lat <- fill_lat_na(as.matrix(dfmat))

请注意,此处没有下限检查,因此,例如,如果您的第一行的纬度中有NA,则此操作将失败。也许还可以改进该功能以引用命名的列。
© www.soinside.com 2019 - 2024. All rights reserved.