R子集匹配连续块

时间:2016-07-21 10:38:26

标签: r

我有一个数据框。

dat <- data.frame(k=c("A","A","B","B","B","A","A","A"),
a=c(4,2,4,7,5,8,3,2),b=c(2,5,3,5,8,4,5,8),
stringsAsFactors = F)

  k a b
1 A 4 2
2 A 2 5
3 B 4 3
4 B 7 5
5 B 5 8
6 A 8 4
7 A 3 5
8 A 2 8

我想基于变量k对连续的块进行子集化。这将是一种标准方法。

#using rle rather than levels
kval <- rle(dat$k)$values
for(i in 1:length(kval))
{
  subdf <- subset(dat,dat$k==kval[i])
  print(subdf)
  #do something with subdf
}

  k a b
1 A 4 2
2 A 2 5
6 A 8 4
7 A 3 5
8 A 2 8

  k a b
3 B 4 3
4 B 7 5
5 B 5 8

  k a b
1 A 4 2
2 A 2 5
6 A 8 4
7 A 3 5
8 A 2 8

所以上面的子集明显不符合我的预期。获得这些结果的任何优雅方式?

k a b
1 A 4 2
2 A 2 5

k a b
1 B 4 3
2 B 7 5
3 B 5 8

k a b
1 A 8 4
2 A 3 5
3 A 2 8

1 个答案:

答案 0 :(得分:2)

我们可以使用rleid中的data.table来创建分组变量

library(data.table) 
setDT(dat)[, grp := rleid(k)]
dat
#    k a b grp
#1: A 4 2   1
#2: A 2 5   1
#3: B 4 3   2
#4: B 7 5   2  
#5: B 5 8   2
#6: A 8 4   3
#7: A 3 5   3
#8: A 2 8   3

我们可以按'grp'进行分组,并使用标准data.table方法在'grp'中执行所有操作。

这是创建'grp'

base R选项
dat$grp <-  with(dat, cumsum(c(TRUE, k[-1]!= k[-length(k)])))