【问题标题】:How to merge rows with consecutive datetime如何合并具有连续日期时间的行
【发布时间】:2016-06-27 12:53:17
【问题描述】:

来自R新手用户的一个问题:我有一个连续的enabled_datetimedisabled_datetime的数据如下所示:

x<-as.data.frame(cbind(
      supplier_id=281743,
      enabled_datetime=c('2016-06-13 13:31:02','2016-06-14 07:39:19','2016-06-14 12:36:03','2016-06-16 13:44:30','2016-06-17 06:42:14'),
      disabled_datetime = c('2016-06-14 07:39:19','2016-06-14 12:36:03','2016-06-16 13:44:30','2016-06-17 06:42:14',  NA),
      discount=c(25,15,15,10,30))
)
x

supplier_id    enabled_datetime   disabled_datetime discount
      281743 2016-06-13 13:31:02 2016-06-14 07:39:19       25
      281743 2016-06-14 07:39:19 2016-06-14 12:36:03       15
      281743 2016-06-14 12:36:03 2016-06-16 13:44:30       15
      281743 2016-06-16 13:44:30 2016-06-17 06:42:14       10
      281743 2016-06-17 06:42:14                <NA>       30

我想变成这样:

supplier_id    enabled_datetime   disabled_datetime discount
      281743 2016-06-13 13:31:02 2016-06-14 07:39:19       25
      281743 2016-06-14 07:39:19 2016-06-16 13:44:30       15
      281743 2016-06-16 13:44:30 2016-06-17 06:42:14       10
      281743 2016-06-17 06:42:14                <NA>       30

即合并具有相同supplier_iddiscount 的行并具有连续的enabled_datetimedisabled_datetime。我能想到的是使用for 循环,有人知道怎么做吗?提前致谢。

【问题讨论】:

  • 请阅读有关how to ask a good question 的信息以及如何提供reproducible example。这将使其他人更容易帮助您。
  • 了解lead()lag()merge
  • 为什么要合并?按供应商 ID 和折扣分组,并安排日期,您可以使用 dplyr 执行此操作...如果我错了,请纠正我? PS:请问为什么要这样投票?
  • @DimitriPetrenko 它不是 dplyr 中使用的“合并”,我的意思是我想将这两行合并为一行。知道该怎么做(在 dplyr 中可以)?

标签: r


【解决方案1】:
 df <- data.frame(supplier_id = c(281743,281743,281743,281743,281743),
                 enabled_datetime = c("2016-06-13 13:31:02","2016-06-14 07:39:19","2016-06-14 12:36:03","2016-06-16 13:44:30","2016-06-17 06:42:14"),
                 disabled_datetime = c("2016-06-14 07:39:19","2016-06-14 12:36:03","2016-06-16 13:44:30","2016-06-17 06:42:14",NA),
                 discount = c(25,15,15,10,30))

df <- df%>%
  mutate(enabled_datetime = as.POSIXct(strftime(enabled_datetime,format="%Y-%m-%d %H:%M:%S")),
         disabled_datetime = as.POSIXct(strftime(disabled_datetime,format="%Y-%m-%d %H:%M:%S")))

subdf1 <- df%>% 
  group_by(supplier_id,discount)  %>%
  mutate(enabled_datetime_lead = lead(enabled_datetime),disabled_datetime_lead = lead(disabled_datetime)) %>%
  filter(disabled_datetime==enabled_datetime_lead) %>% mutate(disabled_datetime = disabled_datetime_lead) %>% 
  select(-enabled_datetime_lead,-disabled_datetime_lead) %>% ungroup()

subdf2<- anti_join(df,resdf,by=c("supplier_id","discount"))

resdf <- full_join(subdf1,subdf2,,by=c("supplier_id","discount"))

这样的结果是

supplier_id    enabled_datetime   disabled_datetime discount
        <dbl>              <time>              <time>    <dbl>
1      281743 2016-06-14 07:39:19 2016-06-16 13:44:30       15
2      281743 2016-06-13 13:31:02 2016-06-14 07:39:19       25
3      281743 2016-06-16 13:44:30 2016-06-17 06:42:14       10
4      281743 2016-06-17 06:42:14                <NA>       30

更改说明:将最终语句从full_join 更改为union,因为最终结果有两个新列。该行为与最初发现的行为不同。

【讨论】:

  • 解决方案提示错误,并且不会产生您引用的结果。不应该是subdf2&lt;- anti_join(df,resdf,by=c("supplier_id","discount"))吗?
  • @macchiavalley,什么是 resdf?我找不到它!
猜你喜欢
  • 2020-12-08
  • 1970-01-01
  • 1970-01-01
  • 2017-02-12
  • 2022-06-28
  • 1970-01-01
  • 2013-03-24
  • 2013-08-30
  • 1970-01-01
相关资源
最近更新 更多