【问题标题】:How to get the unique values of a variable in new columns in a R Data frame?如何在 R 数据框中的新列中获取变量的唯一值?
【发布时间】:2015-04-21 20:31:55
【问题描述】:

样本数据

mydf <- data.frame(Vehicle.ID = c(1,1,1,1,1,1,1,1), Frame.ID = c(1,2,3,4,5,6,7,8),
           Lane = c(1,1,2,2,2,3,3,3), lane.change = c(".", ".", "yes", ".", ".","yes",".","."),
           Preceding.Vehicle.ID = c(10,10,5,5,5,6,6,6),
           Following.Vehicle.ID = c(20,20,50,50,50,30,30,30))

数据说明

Vehicle.ID:车辆 ID
Frame.ID:帧数(1 帧 = 0.1 秒)
车道:当前占用车道的编号
lane.change:“.”表示车辆在此帧中没有变道,“是”表示车辆在此帧中变道
Preceding.Vehicle.IDFollowing.Vehicle.ID :给定帧中当前车道上前车和后车的 ID。

我想做什么:

我想找:
1.车辆占用的所有车道。当前车道在“车道”列中给出。车辆移动到的所有其他车道都是目标车道。我想创建包含所有目标车道的车道编号的新列,即 target.lane1target.lane2 等。
2. 同样,我想将所有前车 ID 和后车 ID 放入新列中,即目标车道 1 和 2 中的前车:PVtl1,PVtl2,目标车道 1 和 2 中的后车:FVtl1,FVtl2。

最终所需的数据框形式:

mydf.final <- mydf %>%
  mutate(target.lane1 = 2, PVtl1 = 5, FVtl1 = 50, 
         target.lane2 = 3, PVtl2 = 6, FVtl2 = 30)

我尝试过的:

老实说,我不知道该怎么做。我尝试使用:

> mydf <- mydf %>%
+   mutate(pvtl1 = data.frame(unique(Preceding.Vehicle.ID)))
Error: not compatible with STRSXP

但是得到你所看到的错误。

请指导我。我想为此使用dplyr

编辑:

我尝试过使用for loop,它适用于这个示例数据:

for (i in 1:length(unique(mydf$Lane))){
  mydf[,paste("target.lane",i, sep=".")] =  unique(mydf$Lane)[i]
  mydf[,paste("PVtl",i, sep=".")] =  unique(mydf$Preceding.Vehicle.ID)[i]
  mydf[,paste("FVtl",i, sep=".")] =  unique(mydf$Following.Vehicle.ID)[i]
}

在这里,target.lane.1、PVtl1 和 FVtl1 是无用的,因为它们只包含第一个当前车道的信息,而不是目标车道,所以我可以稍后将它们删除。
但是原始数据很大,并且有更多独特的 Vehicle.ID。使用for loop 似乎不是一个明智的主意。如何使用dplyr 更快地达到同样的效果?

EDIT 2(适合我的 dplyr 解决方案)

看来今天没有人在帮助心情。我想出了一个dplyr 的解决方案,如果有大约 8 个车道变换,可以应用它:

mydf %>%
  mutate(ul = n_distinct(Lane),
         target.lane.1 = unique(Lane)[ul - (ul-2)],
         PVtl1 = Preceding.Vehicle.ID[match(target.lane.1, Lane)],
         FVtl1 = Following.Vehicle.ID[match(target.lane.1, Lane)],
         target.lane.2 = unique(Lane)[ul - (ul-3)],
         PVtl2 = Preceding.Vehicle.ID[match(target.lane.2, Lane)],
         FVtl2 = Following.Vehicle.ID[match(target.lane.2, Lane)],
         target.lane.3 = unique(Lane)[ul - (ul-4)],
         PVtl3 = Preceding.Vehicle.ID[match(target.lane.3, Lane)],
         FVtl3 = Following.Vehicle.ID[match(target.lane.3, Lane)],
         target.lane.4 = unique(Lane)[ul - (ul-5)],
         PVtl4 = Preceding.Vehicle.ID[match(target.lane.4, Lane)],
         FVtl4 = Following.Vehicle.ID[match(target.lane.4, Lane)],
         target.lane.5 = unique(Lane)[ul - (ul-6)],
         PVtl5 = Preceding.Vehicle.ID[match(target.lane.5, Lane)],
         FVtl5 = Following.Vehicle.ID[match(target.lane.5, Lane)],
         target.lane.6 = unique(Lane)[ul - (ul-7)],
         PVtl6 = Preceding.Vehicle.ID[match(target.lane.6, Lane)],
         FVtl6 = Following.Vehicle.ID[match(target.lane.6, Lane)],
         target.lane.7 = unique(Lane)[ul - (ul-8)],
         PVtl7 = Preceding.Vehicle.ID[match(target.lane.7, Lane)],
         FVtl7 = Following.Vehicle.ID[match(target.lane.7, Lane)],
         target.lane.8 = unique(Lane)[ul - (ul-9)],
         PVtl8 = Preceding.Vehicle.ID[match(target.lane.8, Lane)],
         FVtl8 = Following.Vehicle.ID[match(target.lane.8, Lane)],
         target.lane.9 = unique(Lane)[ul - (ul-10)],
         PVtl9 = Preceding.Vehicle.ID[match(target.lane.9, Lane)],
         FVtl9 = Following.Vehicle.ID[match(target.lane.9, Lane)],
         target.lane.final = unique(Lane)[ul],
         PVtlf = Preceding.Vehicle.ID[match(target.lane.final, Lane)],
         FVtlf = Following.Vehicle.ID[match(target.lane.final, Lane)])

不过,我想修改我的代码,以便根据观察到的车道变化次数创建新列。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    我将通过创建包含感兴趣的新列的数据集,然后使用 left_join 将新数据集连接回原始数据集来解决此问题。我将观察到的车道变化数量的信息添加到数据集中,因此新列的数量可以基于观察到的车道变化的数量。大部分工作是使用tidyr 中的函数重塑数据集以创建新列标题(使用gatherunite),然后制作新列(spread)。我没有按所需的顺序放置新列,但您当然可以这样做。

    如果您有多个 Vehicle.ID 值,下面的代码应该可以工作。如果您只有一个Vehicle.ID,则不需要group_by

    library(dplyr)
    library(tidyr)
    
    mydf %>%
        filter(lane.change == "yes") %>%
        group_by(Vehicle.ID) %>%
        mutate(order = 1:n()) %>%
        select(-Frame.ID, -lane.change) %>%
        rename(target.lane = Lane,  Pvtl = Preceding.Vehicle.ID, FVtl = Following.Vehicle.ID) %>%
        gather(group, number, target.lane, Pvtl, FVtl) %>%
        unite(group1, group, order, sep = "") %>%
        spread(group1, number) %>%
        left_join(mydf, .)
    

    【讨论】:

    • 谢谢!我不知道renamegatherunitespread
    猜你喜欢
    • 1970-01-01
    • 2020-11-13
    • 2014-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多