【问题标题】:In R: Duplicate rows except for the first row based on condition在 R 中:根据条件重复除第一行之外的行
【发布时间】:2015-02-27 14:45:15
【问题描述】:

我有一个 data.table dt:

names <- c("john","mary","mary","mary","mary","mary","mary","tom","tom","tom","mary","john","john","john","tom","tom")
dates <- c(as.Date("2010-06-01"),as.Date("2010-06-01"),as.Date("2010-06-05"),as.Date("2010-06-09"),as.Date("2010-06-13"),as.Date("2010-06-17"),as.Date("2010-06-21"),as.Date("2010-07-09"),as.Date("2010-07-13"),as.Date("2010-07-17"),as.Date("2010-06-01"),as.Date("2010-08-01"),as.Date("2010-08-05"),as.Date("2010-08-09"),as.Date("2010-09-03"),as.Date("2010-09-04"))
shifts_missed <- c(2,11,11,11,11,11,11,6,6,6,1,5,5,5,0,2)
shift <- c("Day","Night","Night","Night","Night","Night","Night","Day","Day","Day","Day","Night","Night","Night","Night","Day")

df <- data.frame(names=names, dates=dates, shifts_missed=shifts_missed, shift=shift)
dt <- as.data.table(df)

names   dates       shifts_missed   shift
john    2010-06-01  2               Day
mary    2010-06-01  11              Night
mary    2010-06-05  11              Night
mary    2010-06-09  11              Night
mary    2010-06-13  11              Night
mary    2010-06-17  11              Night
mary    2010-06-21  11              Night
tom     2010-07-09  6               Day
tom     2010-07-13  6               Day
tom     2010-07-17  6               Day
mary    2010-06-01  1               Day
john    2010-08-01  5               Night
john    2010-08-05  5               Night
john    2010-08-09  5               Night
tom     2010-09-03  0               Night
tom     2010-09-04  2               Day

最终,我想要的是得到以下内容:

names   dates       shifts_missed   shift    count
john    2010-06-01  2               Day      1
mary    2010-06-01  11              Night    1
mary    2010-06-05  11              Night    1
mary    2010-06-09  11              Night    1
mary    2010-06-13  11              Night    1
mary    2010-06-17  11              Night    1
mary    2010-06-21  11              Night    1
tom     2010-07-09  6               Day      1
tom     2010-07-13  6               Day      1
tom     2010-07-17  6               Day      1
mary    2010-06-01  1               Day      1
john    2010-08-01  5               Night    1
john    2010-08-05  5               Night    1
john    2010-08-09  5               Night    1
tom     2010-09-03  0               Night    0
tom     2010-09-04  2               Day      1
john    2010-06-01  2               Night    1
mary    2010-06-05  11              Day      1
mary    2010-06-09  11              Day      1
mary    2010-06-13  11              Day      1
mary    2010-06-17  11              Day      1
mary    2010-06-21  11              Day      1
tom     2010-07-09  6               Night    1
tom     2010-07-13  6               Night    1
tom     2010-07-17  6               Night    1
john    2010-08-05  5               Day      1
john    2010-08-09  5               Day      1
tom     2010-09-04  2               Night    1

如您所见,后半部分数据几乎与前半部分重复。但是,如果 shifts_missed = 0,则不应重复,如果 shifts_missed 为奇数,则不应重复第一行,但应重复其余行。然后它应该在 count 列中为所有添加 1,除非 shifts_missed = 0。

我看到一些关于 !duplicate 或 unique 的答案,但 shifts_missed 中的这些值并不是唯一的。我确信这并不过分复杂,可能是一个多步骤的过程,但我不知道如何隔离奇数 shifts_missed 列的第一行。

【问题讨论】:

  • 有些东西我不明白。当您说“第一行不应重复,而其余行应重复”时,您如何确定哪些行是一组。它们是否必须具有相同的“名称”和相同的“shifts_missed”值?例如,“mary 2010-06-01 1”不重复。那是因为它不是包含“mary 2010-06-21 11”的组的延续
  • 零碎的dplyr 解决方案是零碎地创建数据表的后半部分:filter out shifts_missed == 0,过滤奇数 shifts_missed,然后 group_by 您的重复标准和使用slice(-1) 删除第一行,最后使用ifelse 创建一个新列。然后你可以rbind这个修改后的表到你原来的。

标签: r data.table


【解决方案1】:
dt[, is.in := if(shifts_missed[1] %% 2 == 0) T else c(F, rep(T, .N-1))
   , by = .(names, shift)]
rbind(dt, dt[is.in & shifts_missed != 0]) 

添加额外的列部分应该很明显。

【讨论】:

  • 这非常有效。谢谢!我怎样才能让它将新行从 Day 更改为 Night 并将 Night 更改为 Day?
  • @AndrewRussell res[, shift := ifelse(shift == 'Day', 'Night', 'Day')] 也许
  • 这不会改变所有这些吗?我只想切换 rbind 添加的新行。
  • @AndrewRussell 没有仔细阅读您的评论 - 然后只需修改该位:rbind(dt, dt[...][, shift := ...])
  • 那仍然做同样的事情。除非我完全错误地实施它。
猜你喜欢
  • 2017-09-12
  • 1970-01-01
  • 2019-02-13
  • 2015-05-11
  • 1970-01-01
  • 2012-09-07
  • 1970-01-01
  • 2019-01-13
  • 2020-09-02
相关资源
最近更新 更多