按连续递增ID对数据帧行进行分组

时间:2016-11-11 12:34:56

标签: r dataframe grouping sequential

我对编程艺术(循环等等)相当陌生。如果能得到我的方法是否正常或者如果它是关于它肯定需要优化的话,我会感激不尽用于更大的样本。

目前我有大约20 000个观察结果,其中一列是收据的ID。我想要实现的是将每一行分配给一个组,该组由以n + 1格式升序的ID组成。如果此规则被破坏,则应创建新组,直到规则再次中断。

为了说明,假设我有这个表(重要的是,ID不一定是唯一的,可以重复,就像我的例子中的ID 10):

MyTable <- data.frame(ID = c(1,2,3,4,6,7,8,10,10,11,17,18,19,200,201,202,2010,2011,2013))

MyTable

    ID
    1
    2
    3
    4
    6
    7
    8
    10
    10
    11
    17
    18
    19
    200
    201
    202
    2010
    2011
    2013

我的分组结果应该如下:

    ID    GROUP
    1      1
    2      1
    3      1
    4      1
    6      2
    7      2
    8      2
    10     3
    10     3
    11     3
    17     4
    18     4
    19     4
    200    5
    201    5
    202    5
    2010   6
    2011   6
    2013   7

我使用dplyr以递增的方式对ID进行排序。然后创建了变量MyData $ Group,我简单地填充了1&#39; s。

rep(1,length(MyTable$ID)

for (i in 2:length(MyTable$ID) ) {
  if(MyTable$ID[i] == MyTable$ID[i-1]+1 | MyTable$ID[i] == MyTable$ID[i-1]) {
    MyTable$ID[i] <- MyTable$GROUP[i-1]
     } else {
       MyTable$GROUP[i] <- MyTable$GROUP[i-1]+1
  }
}

这段代码对我有用,我很容易得到结果。但是,我想知道在更有经验的程序员看来,这段代码会被视为&#34;坏&#34;,&#34;平均&#34;,&#34;好&#34;或者你提出的任何等级。

编辑:我确信这个话题已经被触及,而不是反对。虽然,主要区别在于我想在这里触及优化主题,看看我的方法是否符合标准。

谢谢!

1 个答案:

答案 0 :(得分:3)

简而言之:

MyTable$Group <- cumsum(c(1, diff(MyTable$ID) != 1))
#     ID Group
#1     1     1
#2     2     1
#3     3     1
#4     4     1
#5     6     2
#6     7     2
#7     8     2
#8    10     3
#9    11     3
#10   12     3
#11   17     4
#12   18     4
#13   19     4
#14  200     5
#15  201     5
#16  202     5
#17 2010     6
#18 2011     6
#19 2013     7

您正在搜索向量Mytable $ ID中的所有差异,这些差异不是1,因此这是您的“休息”。然后你cumsum所有这些价值观。如果您不知道cumsum,请键入?cumsum。 这就是全部!

更新:使用重复ID,您可以使用:

MyTable <- data.frame(ID = c(1,2,3,4,6,7,8,10,10,11,17,18,19,200,201,202,2010,2011,2013))
MyTable$Group <- cumsum(c(1, !diff(MyTable$ID) %in% c(0,1) ))

#     ID Group
#1     1     1
#2     2     1
#3     3     1
#4     4     1
#5     6     2
#6     7     2
#7     8     2
#8    10     3
#9    10     3
#10   11     3
#11   17     4
#12   18     4
#13   19     4
#14  200     5
#15  201     5
#16  202     5
#17 2010     6
#18 2011     6
#19 2013     7