操作重复标识符时避免循环

时间:2015-05-18 13:57:49

标签: r loops identifier

我经常在R中进行基本操作,因为我必须控制唯一标识符。

我大部分时间都使用“长格式”数据。

dt <- data.frame(id = c(rep("A1", 3), rep("B1", 3)),
             activity = c(15,17,12,3,4,15),
             begin = c( 0, 0, 1, 0, 1, 2 ) )

例如,按标识符计算时间或观察

dt$time <- 1
for(i in 2:nrow(dt)){
  if(dt[i,'id'] == dt[i-1, 'id'])
  {
    dt[i,'time'] <- dt[i-1,'time'] + 1
  }
}

或仔细检查重复数据

dt$zerocheck = 0 
for(i in 2:nrow(dt)){
  if( dt[i,'id'] == dt[i-1, 'id'] & 
        dt[i,'begin'] == dt[i-1, 'begin'] )  
  {
   dt$zerocheck[i] <- 1
  }
}

我猜答案会像id一样聚合,但我不完全确定。

merge(dt, aggregate(time ~ id, dt, "max"), by=c("id"), all.X=T)

为避免做循环,有什么建议吗?

2 个答案:

答案 0 :(得分:4)

使用data.table

可以简化这些操作
require(data.table)
setDT(dt)[, `:=`(time = seq_len(.N), zerocheck = begin == shift(begin)), by = id]

答案 1 :(得分:1)

要添加到其他示例,您还可以使用dplyr

library(dplyr)
dt %>% group_by(id) %>% 
  mutate(time = row_number()) %>% # creates the control for identifier
  mutate(zerocheck= ifelse(begin==lag(begin), 1, 0)) # checks for repeated data

或者等效地你可以使用如下的单个mutate函数:

dt %>% 
  group_by(id) %>% 
  mutate(time = row_number(), 
         zerocheck=begin==lag(begin))

第一个查询有输出:

Source: local data frame [6 x 5]
Groups: id

  id activity begin time zerocheck
1 A1       15     0    1        NA
2 A1       17     0    2         1
3 A1       12     1    3         0
4 B1        3     0    1        NA
5 B1        4     1    2         0
6 B1       15     2    3         0

对于zerocheck情况,我只使用滞后来检查先前的值是否与当前值相同。这模仿了你问题中的代码。当然,如果你想检查别的东西,你可以很容易地改变谓词。