【问题标题】:Assigning values to a group based on previous rows in R根据 R 中的先前行将值分配给组
【发布时间】:2016-04-01 19:55:57
【问题描述】:

我有一个这样的数据表:

  ID Type
  1    I
  1    A
  1    A
  2    I
  2    A
  2    I  
  2    C
  2    I
  2    I

我想添加如下的列序列:

   ID Type Seq
   1    I   1
   1    A   1
   1    A   1
   2    I   1
   2    A   1
   2    I   2
   2    C   2
   2    I   3
   2    I   4

逻辑是:
Seq = previous_row_for_user_where_I_occurs +1,当 Type=I
Seq = 用户上一次出现的 I,当 Type=A 或 C

所以基本上,对于给定的用户编号,所有 I 的出现都是按顺序出现的。如果 A 或 C 出现在两者之间,则将其分配给它之前出现的 I 的值。 ID 已使用日期字段进行排序。

我也参考了以下内容,但它没有帮助,因为如果“A”为用户出现两次,则第二次出现的编号不正确。
Assigning values in a sequence depending on previous row in R

我现在使用 for 循环,因为我有 1000 万行,所以需要几个小时。

【问题讨论】:

  • 第一个数据表中缺少 Type 列。此外,您的逻辑对于随后的重复也不清楚。随着更多倍数的出现,计数会与 3,4,... 一致吗?
  • 我在原问题中做了修改。

标签: r


【解决方案1】:

我认为data.table 包是解决这个问题的最佳选择:

> dt[, Seq := cumsum(Type == "I"), by = ID]
> dt
   ID Type Seq
1:  1    I   1
2:  1    A   1
3:  1    A   1
4:  2    I   1
5:  2    A   1
6:  2    I   2
7:  2    C   2
8:  2    I   3
9:  2    I   4

【讨论】:

  • 您的解决方案只是巧合应用于示例。尝试添加第三个 ID。例如,10: 3 I
  • @PierreLafortune 详细说明
  • 您的解决方案是在每组之后将序列重置为 0。但也许这就是预期的输出。如果没有,OP 会澄清。
  • @PierreLafortune 我明白了,是的,如果新 ID 的第一个类型不是 I,这将变为 0。但我也意识到他没有具体说明应该发生什么,所以我很好奇
  • 解决方案很完美。如果 A 或 C 是​​第一条记录,则应为其分配 Seq 编号 0。感谢所有帮助。我将用 1000 万条记录运行它,希望它运行得更快。
【解决方案2】:

我们可以使用dplyr

library(dplyr)
df1 %>%
  group_by(ID) %>%
  mutate(Seq = cumsum(Type=="I"))   

【讨论】:

  • 感谢您的回复。 dplyr 也解决了我的目的,但需要几秒钟才能运行大量数据。另一方面 data.table 命令在眨眼之间运行。
猜你喜欢
  • 2019-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多