【问题标题】:How to compare two consecutive rows with a reference value in R?如何将两个连续的行与 R 中的参考值进行比较?
【发布时间】:2014-02-21 03:10:16
【问题描述】:

我有一个车辆轨迹数据框。这是一张快照:

> head(df)
  vehicle frame globalx class velocity lane
1       2    43 6451214     2    37.76    2
2       2    44 6451217     2    37.90    2
3       2    45 6451220     2    38.05    2
4       2    46 6451223     2    38.18    2
5       2    47 6451225     2    38.32    2
6       2    48 6451228     2    38.44    2

其中,vehicle= 车辆 id(重复,因为在多个时间帧中观察到同一车辆),frame= 观察到的时间帧的帧 id,globalx = 车辆前中心的 x 坐标,class=类型车辆(1=摩托车,2=汽车,3=卡车),速度=车辆的速度,以英尺/秒为单位,车道=车道数(有 6 条车道)。我认为下面的插图将更好地解释这个问题: “帧”表示十分之一秒,即一帧长 0.1 秒。在“t”帧,车辆具有全局坐标 x(t),在“t-1”帧(0.1 秒前)为 x(t-1)。参考位置是'U'(globalx = 6451179.1116),我只想要一个名为'u'的df中的新列,它在车辆的globalx大于'U'处的参考坐标和前一个的行​​中具有'yes'这辆车的连续 globalx 坐标小于“U”处的参考坐标。这意味着如果 df 有 100 辆车,那么“u”列中将有 100 个“是”,因为每辆车都会满足上述条件一次。我试图通过使用 ifelse 运行该函数来做到这一点,并且还尝试使用 for 循环来做同样的事情,但它对我不起作用。输出应该有一个新列:

vehicle frame globalx class velocity lane u 

我尝试在 for 循环和函数中使用 ifelse,但它对我不起作用。

【问题讨论】:

  • ifelse 是矢量化的。不需要forwithin(df, u <- globalx > your.coord)
  • @mlt 有 2 个条件,globalx 在帧 't' 例如第 45 帧应大于参考坐标 u,并且在连续的前一帧 44 处,globalx 应小于参考坐标,如图所示。如何指定 R 应该查看连续帧?我试过 globalx[i]>6451179.1116 & globalx[i-1]
  • 类似ref < globalx && (globalx-ref > c(diff(globalx), 0))。检查c() 中的参数顺序。请注意,如果您有不同的车辆 ID,最好使用来自 plyr 或类似网站的ddply
  • 太棒了。让我们根据中值定理给人们更多的超速罚单。

标签: r


【解决方案1】:

我假设数据框主要针对vehicle 排序,其次针对globalx。如果不是,你可以这样做:

idx <- with(df,order(vehicle,globalx))
df <- df[idx,]

现在,您可以使用以下矢量化操作来执行它:

# example reference line
U <- 6451220
# adding the extra column
samecar <- duplicated(df[,"vehicle"])
passU <- c(FALSE,diff(sign(df[,"globalx"]-U+1e-10))>0)
df[,"u"] <- ifelse(samecar & passU,"yes","no")

【讨论】:

    【解决方案2】:

    这是我的解决方案:

    首先根据您提供的数据创建虚拟数据(我已将其保存到桌面上的data.txt),复制数据,以便有两辆具有相同数据但车辆ID不同的汽车:

    library(plyr)
    df <- read.table("~/Desktop/data.txt",header=T)
    df.B <- df; df.B$vehicle = 3 #For demonstration
    df <- rbind(df,df.B); rm(df.B)
    

    然后我们可以构建一个函数来处理:

    mvt <- function(xref=NULL,...,data=df){
      if(!is.numeric(xref)) #Input must be numeric
        stop("xref must be numeric",call.=F)
      xref = xref[1]
    
      ##Split on vehicle and process.
      ddply(data,"vehicle",function(d){
        L = nrow(d) #Number of Rows
        d$u = FALSE #Default to Not crossing
    
        #One or more rows can be checked.
        if(L == 1)
          d$u = (d$globalx > xref)
        else if(L > 1){
          ix <- which(d$globalx[2:L] > xref & d$globalx[1:(L-1)] <= xref)
          if(length(ix) > 0)
            d$u[ix + 1] = TRUE
        }
    
        #done
        return(d)
      })
    }
    

    可以通过以下方式使用:

    mvt(6451216)
    mvt(6451217)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多