【问题标题】:R数据框设置属性依赖于先前和随后的属性值
【发布时间】:2022-01-23 13:54:42
【问题描述】:

我有一个带有来自跟踪设备的事件日志的数据框。它记录了事件的类型(停留在原地或轨道/移动)、事件的名称(停留的家庭/工作/其他、轨道的交通模式)、距离和事件的开始日期时间。可以在不同地点停留之间登录多个曲目/模式更改。

type = c('place', 'track', 'track', 'place', 'track', 'place')
name = c('home', 'walk', 'bicycle', 'work', 'walk', 'other')
distance = c(0, 1120, 2300, 0, 4000, 0)
startdate = c('2021-12-19 10:00:00', '2021-12-19 11:00:00', '2021-12-19 11:05:00', '2021-12-19 11:15:00', '2021-12-19 12:00:00', '2021-12-19 12:30:00')

df = data.frame(type, name ,distance, startdate)

我希望能够为所有曲目分配一个新属性,指示记录曲目的来源和位置,例如最后一个和下一个记录的地方是什么,不包括可能相互跟随的所有轨道:

fromto = c(NA, 'home-work', 'home-work', NA, 'work-other', NA)
df = data.frame(type, name ,distance, startdate, fromto)

如果设置更简单,我可能会使用 dplyr 的滞后函数或各种类型的 cumsum,但是由于多个轨道可以相互跟随,我需要在前后行查找“名称”属性。

数据集通常会很大;是否有不需要实现循环的 R 解决方案?

【问题讨论】:

    标签: r dataframe dplyr


    【解决方案1】:

    从稍微不同的角度来看,您可以添加一个 id 列,过滤所有时间类型 == "place",然后使用 mutate、paste() 和 lead() 创建 fromto 列,保存这个到数据框,然后将其重新加入到您的原始df。然后您可以 tidyr::fill() fromto 列,这将允许您进行分组。

    library(dplyr)
    library(tidyr)
    df <- df %>% mutate(id = row_number())
    changes <- df %>%
        filter(type == "place") %>%
        mutate(fromto = paste(name, lead(name, 1), sep = "-")) %>%
       select(id, fromto)
    
    df <- df %>% 
        left_join(changes, by = "id") %>%
        fill(fromto)
    
    

    然后您可以过滤 type == "track":

    df %>% filter(type == "track")
    

    【讨论】:

      【解决方案2】:

      一个可能的解决方案:

      library(tidyverse)
      
      type = c('place', 'track', 'track', 'place', 'track', 'place')
      name = c('home', 'walk', 'bicycle', 'work', 'walk', 'other')
      distance = c(0, 1120, 2300, 0, 4000, 0)
      startdate = c('2021-12-19 10:00:00', '2021-12-19 11:00:00', '2021-12-19 11:05:00', '2021-12-19 11:15:00', '2021-12-19 12:00:00', '2021-12-19 12:30:00')
      
      df = data.frame(type, name ,distance, startdate)
      
      df %>% 
        mutate(id = row_number()) %>% 
        filter(type == "place") %>% 
        mutate(fromto = str_c(lag(name), name, sep="_")) %>% 
        full_join(mutate(df, id = row_number())) %>% 
        arrange(id) %>% 
        fill(fromto, .direction = "up") %>% 
        mutate(fromto = if_else(type == "place", NA_character_, fromto), id=NULL)
      
      #>    type    name distance           startdate     fromto
      #> 1 place    home        0 2021-12-19 10:00:00       <NA>
      #> 2 track    walk     1120 2021-12-19 11:00:00  home_work
      #> 3 track bicycle     2300 2021-12-19 11:05:00  home_work
      #> 4 place    work        0 2021-12-19 11:15:00       <NA>
      #> 5 track    walk     4000 2021-12-19 12:00:00 work_other
      #> 6 place   other        0 2021-12-19 12:30:00       <NA>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-04-17
        • 2013-01-05
        • 1970-01-01
        • 2014-08-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多