【问题标题】:Remove the first row from each group if the second row meets a condition如果第二行满足条件,则从每个组中删除第一行
【发布时间】:2019-09-13 14:25:35
【问题描述】:

这是我的数据集示例:

df=data.frame(id=c("9","9","9","5","5","5","4","4","4","4","4","20","20"),
  Date=c("11/29/2018","11/29/2018","11/29/2018","5/25/2018","2/13/2019","2/13/2019","6/7/2018",
    "6/15/2018","6/20/2018","8/17/2018","8/20/2018","12/25/2018","12/25/2018"), 
  Buyer= c("John","John","John","Maria","Maria","Maria","Sandy","Sandy","Sandy","Sandy","Sandy","Paul","Paul"))

我需要计算我已经完成的日期与数据集之间的差异,然后看起来像:

| id |    Date    | Buyer | diff |
|----|:----------:|------:|------|
| 9  | 11/29/2018 |  John | NA   |
| 9  | 11/29/2018 |  John | 0    |
| 9  | 11/29/2018 |  John | 0    |
| 5  | 5/25/2018  | Maria | -188 |
| 5  | 2/13/2019  | Maria | 264  |
| 5  | 2/13/2019  | Maria | 0    |
| 4  | 6/7/2018   | Sandy | -251 |
| 4  | 6/15/2018  | Sandy | 8    |
| 4  | 6/20/2018  | Sandy | 5    |
| 4  | 8/17/2018  | Sandy | 58   |
| 4  | 8/20/2018  | Sandy | 3    |
| 20 | 12/25/2018 | Paul  | 127  |
| 20 | 12/25/2018 | Paul  | 0    |

现在,如果每组'di​​ff'列中第二行的值大于或等于5,那么我需要删除每组的第一行。例如,对于 ID 为“5”的买方“Maria”,差异值 264 大于 5,因此我想删除该组中的第一行,即 ID 为“5”的买方“Maria”,日期为'5/25/2018',差异为 '-188'

下面是我的代码示例:

df1=df %>% group_by(Buyer,id) %>%
  mutate(diff = c(NA, diff(Date))) %>%
  filter(!(diff >=5 & row_number() == 1))

问题是上面的代码选择了第一行而不是第二行,我不知道如何为每个组指定第 2 行,其中 diff 值应该大于或等于 5。

我的预期输出应该是这样的:

| id |    Date    | Buyer | diff |
|----|:----------:|------:|------|
| 9  | 11/29/2018 |  John | NA   |
| 9  | 11/29/2018 |  John | 0    |
| 9  | 11/29/2018 |  John | 0    |
| 5  | 2/13/2019  | Maria | 264  |
| 5  | 2/13/2019  | Maria | 0    |
| 4  | 6/15/2018  | Sandy | 8    |
| 4  | 6/20/2018  | Sandy | 5    |
| 4  | 8/17/2018  | Sandy | 58   |
| 4  | 8/20/2018  | Sandy | 3    |
| 20 | 12/25/2018 | Paul  | 127  |
| 20 | 12/25/2018 | Paul  | 0    |

【问题讨论】:

  • df 中的日期与您打印的数据不匹配。还将diff 列添加到df。也许在你使用它时将其命名为diffs,以避免与diff()发生冲突。
  • @Shree 我已经更正了。我的原始数据集没有 diff 列。我需要稍后再创建它,我已经在代码中指定了。
  • 从我们的角度来看,这只是您已经计算过的输入,因此您应该包含在数据中或包含代码来计算它。不管怎样,现在都无所谓了。看看下面的答案是否有帮助。

标签: r group-by date-difference


【解决方案1】:

我想你忘了在df 中提供diff 列。我创建了一个名为diffs 的函数,这样它就不会与函数diff() 冲突。 -

library(dplyr)

df1 %>% 
  group_by(id) %>% 
  mutate(diffs = c(NA, diff(as.Date(Date, format = "%m/%d/%Y")))) %>% 
  filter(
    n() == 1 |         # always keep if only one row in group
    row_number() > 1 | # always keep all row_number() > 1
    diffs[2] < 5       # keep 1st row only if 2nd row diffs < 5
  ) %>% 
  ungroup()

# A tibble: 11 x 4
   id    Date       Buyer diffs
   <chr> <chr>      <chr> <dbl>
 1 9     11/29/2018 John     NA
 2 9     11/29/2018 John      0
 3 9     11/29/2018 John      0
 4 5     2/13/2019  Maria   264
 5 5     2/13/2019  Maria     0
 6 4     6/15/2018  Sandy     8
 7 4     6/20/2018  Sandy     5
 8 4     8/17/2018  Sandy    58
 9 4     8/20/2018  Sandy     3
10 20    12/25/2018 Paul     NA
11 20    12/25/2018 Paul      0

数据 -

我加了stringsAsFactors = FALSE

df1 <- data.frame(id=c("9","9","9","5","5","5","4","4","4","4","4","20","20"),
  Date=c("11/29/2018","11/29/2018","11/29/2018","5/25/2018","2/13/2019","2/13/2019","6/7/2018",
    "6/15/2018","6/20/2018","8/17/2018","8/20/2018","12/25/2018","12/25/2018"), 
  Buyer= c("John","John","John","Maria","Maria","Maria","Sandy","Sandy","Sandy","Sandy","Sandy","Paul","Paul")
  , stringsAsFactors = F)

【讨论】:

  • @Shree 你能解释一下你的代码中使用的逻辑吗?
  • @hk2 刚刚将解释添加为代码 cmets。要进行可视化,请创建三列,每列具有一个过滤条件,并沿它们应用 OR。
【解决方案2】:

也许我想多了,但这里有一个想法,

df8 %>% 
 mutate(Date = as.Date(Date, format = '%m/%d/%Y')) %>% 
 mutate(diff = c(NA, diff(Date))) %>% 
 group_by(id) %>% 
 mutate(diff1 = as.integer(diff >= 5) + row_number()) %>% 
 filter(diff1 != 1 | lead(diff1) != 3) %>% 
 select(-diff1)

给出,

# A tibble: 11 x 4
# Groups:   id [4]
   id    Date       Buyer  diff
   <fct> <date>     <fct> <dbl>
 1 9     2018-11-29 John     NA
 2 9     2018-11-29 John      0
 3 9     2018-11-29 John      0
 4 5     2019-02-13 Maria   264
 5 5     2019-02-13 Maria     0
 6 4     2018-06-15 Sandy     8
 7 4     2018-06-20 Sandy     5
 8 4     2018-08-17 Sandy    58
 9 4     2018-08-20 Sandy     3
10 20    2018-12-25 Paul    127
11 20    2018-12-25 Paul      0

【讨论】:

    猜你喜欢
    • 2021-01-28
    • 2015-10-13
    • 1970-01-01
    • 1970-01-01
    • 2020-09-11
    • 2021-06-06
    • 1970-01-01
    • 2020-09-11
    • 1970-01-01
    相关资源
    最近更新 更多