【问题标题】:create a new column conditional on distance traveled between points in R以 R 中点之间的距离为条件创建一个新列
【发布时间】:2015-11-04 21:26:04
【问题描述】:

我正在尝试以另一列为条件创建一个新列,有点像移动平均线或移动窗口,但基于点之间的距离。以 CO2 为 399.935 的第 2 行为例。我想获得该点 100 m(行进)内所有点的平均值。在我的示例中(查看 CumDist 列),将选择第 1、3、4、5 行来计算平均值。 CumDist 列(*100,000 以米为单位)由累积的行驶距离组成。我有 5000 个点,显然移动窗口的宽度(或行数)会有所不同。

我从 sp 包中测试了over(),但如果多次走同一条路,就会出现问题。我在网上寻找其他解决方案,但没有找到任何可以帮助我的方法。

dput(DF)
structure(list(CO2 = c(399.9350305, 399.9350305, 399.9350305, 
400.0320031, 400.0320031, 400.0320031, 399.7718229, 399.7718229, 
399.7718229, 399.3855075, 399.3855075, 399.3855075, 399.4708139, 
399.4708139, 399.4708139, 400.0362474, 400.0362474, 400.0362474, 
399.7556753, 399.7556753), lon = c(-103.7093538, -103.709352, 
-103.7093492, -103.7093467, -103.7093455, -103.7093465, -103.7093482, 
-103.7093596, -103.7094074, -103.7094625, -103.7094966, -103.709593, 
-103.709649, -103.7096717, -103.7097349, -103.7097795, -103.709827, 
-103.7099007, -103.709924, -103.7099887), lat = c(49.46972027, 
49.46972153, 49.46971675, 49.46971533, 49.46971307, 49.4697124, 
49.46970636, 49.46968214, 49.46960921, 49.46955984, 49.46953621, 
49.46945809, 49.46938994, 49.46935281, 49.46924309, 49.46918635, 
49.46914762, 49.46912566, 49.46912407, 49.46913321),distDiff = c(0.000342016147509882, 
0.000191466419697602, 0.000569046320857002, 0.000240367540492089, 
0.000265977754839834, 0.000103953049523505, 0.000682968856240796, 
0.0028176007969857, 0.00882013898948418, 0.00678966015562509, 
0.00360774024245839, 0.011149423290729, 0.00859796340323456, 
0.00444526066124642, 0.0130344010874029, 0.00709037369666853, 
0.00551435348701512, 0.00587377717110946, 0.00169806309901329, 
0.00479849401022625), CumDist = c(0.000342016147509882, 0.000533482567207484, 
0.00110252888806449, 0.00134289642855657, 0.00160887418339641, 
0.00171282723291991, 0.00239579608916071, 0.00521339688614641, 
0.0140335358756306, 0.0208231960312557, 0.0244309362737141, 0.0355803595644431, 
0.0441783229676777, 0.0486235836289241, 0.0616579847163269, 0.0687483584129955, 
0.0742627119000106, 0.08013648907112, 0.0818345521701333, 0.0866330461803596
)), .Names = c("X12CO2_dry", "coords.x1", "coords.x2", "V1", 
"CumDist"), row.names = 2:21, class = "data.frame")

谢谢,马丁

【问题讨论】:

  • 你为什么没有在你的问题中提到最低限度?
  • 对那个 mra68 感到抱歉。我假设该解决方案对 mean()、min() 或 max() 有效。当我处理我的问题时,我错误地删除了 min() 。感谢您的解决方案。
  • 接受和“谢谢”并不是表扬好答案的唯一方法。
  • 我很抱歉 mra68,但你到底是什么意思?我在 StackOverflow 方面没有太多经验,但如果有其他方法可以将好的答案归功于我,我一定会这样做!
  • 点击答案旁边的向上箭头会使该箭头下方的数字增加 1。这值 10 分,接受 15 分。

标签: r distance moving-average


【解决方案1】:

你用更清洁的解决方案 mra68 打败了我。

这是我的使用几个循环。

####################
for (j in 1:nrow(DF)){#Loop through all rows of your dataset

  CO2list<-NULL ##Need to make a variable before storing to it in the loop

  for(i in 1:nrow(DF)){##Loop through all distances in the table

      if ((abs(DF$CumDist[i]-DF$CumDist[j]))<=0.001) {
        ##Check to see if difference in CumDist<=100/100000 for all entries 
        #CumDist[j] is point with the 100 meter window around it
      CO2list<-c(CO2list,DF$X12CO2_dry[i])
        ##Store your CO2 entries that are within the 100 meter window to a vector
      }

  }
  DF$CO2AVG[j]<-mean(CO2list) 
     #Get the mean of your list and store it to column named CO2AVG

}

【讨论】:

  • 谢谢你们俩。解决方案一更快,但 jscole 的解决方案也允许我采取最低限度。
【解决方案2】:

属于第 i 行的窗口从n[i] 开始,到m[i]-1 结束。因此,第 i 个窗口中 CO2 值的总和为CumCO2[m[i]]-CumCO2[n[i]]。 (请注意,CumCO2 中的索引移动了 1,因为前导 0。)将此 CO2 总和除以窗口大小 m[i]-n[i] 得到新列的值 meanCO2

n <- sapply( df$CumDist,
             function(x){
               which.max( df$CumDist >= x-0.001 )
             }
           )

m <- sapply( df$CumDist,
             function(x){
               which.max( c(df$CumDist,Inf) > x+0.001 )
             }
           )

CumCO2 <- c( 0, cumsum(df$X12CO2) )

meanCO2 <- ( CumCO2[m] - CumCO2[n] ) / (m-n)

.

> n
 [1]  1  1  1  2  3  3  5  8  9 10 11 12 13 14 15 16 17 18 19 20
> m
 [1]  4  5  7  7  8  8  8  9 10 11 12 13 14 15 16 17 18 19 20 21
> meanCO2
 [1] 399.9350 399.9593 399.9835 399.9932 399.9606 399.9606 399.9453 399.7718 399.7718 399.3855 399.3855 399.3855 399.4708 399.4708 399.4708 400.0362
[17] 400.0362 400.0362 399.7557 399.7557
> 

【讨论】:

    猜你喜欢
    • 2019-03-28
    • 2023-03-06
    • 2014-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多