R添加列,指示列中序列的开始和结束

时间:2015-06-11 23:19:56

标签: r sequence

我的数据如下。

names=c(rep("a",4),rep("b",5),rep("c",2))
time=c(1,2,3,4,1,2,3,4,5,1,2)
dd=data.frame(names,time)


dd <- group_by(dd, names)
dd <- mutate(dd, seq=seq_along(names))
extr <- summarise(dd, minw=min(time), maxw=max(time))


> dd
Source: local data frame [11 x 3]
Groups: names

   names time seq
1      a    1   1
2      a    2   2
3      a    3   3
4      a    4   4
5      b    1   1
6      b    2   2
7      b    3   3
8      b    4   4
9      b    5   5
10     c    1   1
11     c    2   2
> extr
Source: local data frame [3 x 3]

  names minw maxw
1     a    1    4
2     b    1    5
3     c    1    2

我需要的最终输出如下。我想添加两个列 - first_indicator和last_indicator,它们将具有值&#34; yes&#34;如果名称和序列的组合分别具有第一个和最后一个值。我怎么能使用上面生成的dd和extr数据帧呢?

   names time seq first_indicator last_indicator
1      a    1   1             yes               
2      a    2   2                               
3      a    3   3                               
4      a    4   4                            yes
5      b    1   1             yes               
6      b    2   2                               
7      b    3   3                               
8      b    4   4                               
9      b    5   5                            yes
10     c    1   1             yes               
11     c    2   2                            yes

3 个答案:

答案 0 :(得分:3)

在基数R中,使用ave

dd$first <- dd$time==1                              #1 is always the start of a group
dd$last  <- dd$time==ave(dd$time,dd$names,FUN=max)  #check against max group value

#   names time first  last
#1      a    1  TRUE FALSE
#2      a    2 FALSE FALSE
#3      a    3 FALSE FALSE
#4      a    4 FALSE  TRUE
#5      b    1  TRUE FALSE
#6      b    2 FALSE FALSE
#7      b    3 FALSE FALSE
#8      b    4 FALSE FALSE
#9      b    5 FALSE  TRUE
#10     c    1  TRUE FALSE
#11     c    2 FALSE  TRUE

使用data.table您可以执行以下操作:

library(data.table)
setDT(dd)[,c("first","last") := list(time==1,time==.N), by=names]

答案 1 :(得分:1)

你可以这样做:

dd %>% 
  group_by(names) %>% 
  mutate(first = ifelse(first(time) == time, "yes", ""), 
         last = ifelse(last(time) == time, "yes", ""))

给出了:

#Source: local data frame [11 x 4]
#Groups: names
#
#   names time first last
#1      a    1   yes     
#2      a    2           
#3      a    3           
#4      a    4        yes
#5      b    1   yes     
#6      b    2           
#7      b    3           
#8      b    4           
#9      b    5        yes
#10     c    1   yes     
#11     c    2        yes

答案 2 :(得分:0)

也许不是最优雅的答案,但是......

extr$first_indicator <- rep("yes", nrow(extr))
extr$last_indicator <- rep("yes", nrow(extr))

dd <- merge(dd, extr[c(1,2,4)], by.x = 1:2, by.y = 1:2, all = TRUE)
dd <- merge(dd, extr[c(1,3,5)], by.x = c(1,3), by.y = 1:2, all = TRUE)

应该有效。当然,如果你需要多次这样做,你可以将它全部包装在一个函数中。