按R中数据框中的序列分组

时间:2016-07-03 01:00:47

标签: r split group-by duplicates data.table

我有数据框,我需要根据月份分成3组。

  • 第1组:第1,2和第1个月第2个月用药改变
  • 第2组:第1,2,3个月第3个月用药改变
  • 第3组:第1,2,3,4个月,向上和向下第4个月用药改变

计算3组使用的每种药物(共5种药物)的频率,平均值,SE。

ID <- c(1,1,2,2,2,2,3,3,3,3,3,4,4,4,5,5,5,5,5,6,6,6,6,7,7,8,8,8,8)
month <- c(1,2,1,2,3,4,1,2,3,4,5,1,2,3,1,2,3,4,5,1,2,3,4,1,2,1,2,3,4)
med <- c(1,1,2,2,2,3,4,4,4,4,4,1,1,1,6,6,7,7,7,3,3,3,3,1,1,5,5,5,5)
mean <-  c(4,6,5,2,3,7,5,7,1,3,6,7,5,2,3,3,3,3,3,5,6,7,8,1,6,4,5,6,7)
df <- data.frame(ID,month,med,mean)
df

    ID month med mean
1   1     1   1    4
2   1     2   1    6
3   2     1   2    5
4   2     2   2    2
5   2     3   2    3
6   2     4   3    7
7   3     1   4    5
8   3     2   4    7
9   3     3   4    1
10  3     4   4    3
11  3     5   4    6
12  4     1   1    7
13  4     2   1    5
14  4     3   1    2
15  5     1   6    3
16  5     2   6    3
17  5     3   7    3
18  5     4   7    3
19  5     5   7    3
20  6     1   3    5
21  6     2   3    6
22  6     3   3    7
23  6     4   3    8
24  7     1   1    1
25  7     2   1    6
26  8     1   5    4
27  8     2   5    5
28  8     3   5    6
29  8     4   5    7

我有8个ID

  • ID = 1,在第1组中,它们使用Med = 1。
  • ID = 2,应该在第3组,Med = 2,如果你检查Med,他们使用2和 3,但是一旦他们保持至少2的第一,我将他们设置在第3组。如果他们在第3个月改变Med,我将他们设置为第2组。如果他们在第2个月改变了med,我将它们设置在第1组。
  • ID = 3,应在第3组中.Med = 4
  • ID = 4,应在第2组中.Med = 1
  • ID = 5,应在第2组中.Med = 6
  • ID = 6,应在第3组中.Med = 3
  • ID = 7,应在第1组中.Med = 1
  • ID = 8,应在第3组中.Med = 5

我的数据很大,我尝试使用data.table但我不知道如何拆分它。

1 个答案:

答案 0 :(得分:1)

如果我理解你的逻辑,可以用这种方式重述,如果没有药物改变,该组将由月数决定。否则将根据药物切换的月份确定,如果是这种情况,您可以使用data.table完成以下操作:

setDT(df)[, list({medSwitch = which(c(0, diff(med)) != 0);
                  Group = ifelse(length(medSwitch) == 0,
                                 ifelse(.N <= 4, .N - 1, 3),
                                 ifelse(min(medSwitch) <= 4, min(medSwitch) - 1, 3))}), .(ID)]
#    ID V1
# 1:  1  1
# 2:  2  3
# 3:  3  3
# 4:  4  2
# 5:  5  2
# 6:  6  3
# 7:  7  1
# 8:  8  3

如果您正在寻找就地变异,即将组添加到原始数据框,而不是如上所述,您可以这样做:

setDT(df)[, Group := list({medSwitch = which(c(0, diff(med)) != 0);
                           ifelse(length(medSwitch) == 0,
                                  ifelse(.N <= 4, .N - 1, 3),
                                  ifelse(min(medSwitch) <= 4, min(medSwitch) - 1, 3))}), .(ID)] 

注意:结果与您想要的输出相匹配,但与您在问题开头定义的条件不同。你的意思是|而不是&