分离个别事件的方法

时间:2015-03-30 13:38:20

标签: r dataframe data-analysis

我有一个大的数据集,每1/2秒观察一次。它代表机器人中的一系列挤奶。因此,一头母牛进入机器人并在测量不同的东西时挤奶。然后牛离开,有一段时间没有牛,直到另一头母牛进入。我为我的数据过度简化的样本编写了代码。

示例数据

set.seed(66)
ID <- rep(c(84,-999,88,-999),c(5,3,7,5))
TimeStamp <- rep(c("09:31:12",NA,"09:45:31",NA),c(5,3,7,5))
VAR1 <- sample(x = 800:3000, 20)
mydf <- data.frame(ID=ID, TimeStamp=TimeStamp, VAR1 = VAR1)
eventIDs <- as.numeric(factor(mydf[, "TimeStamp"], exclude = NULL))
mydf[, "eventIDs"] <- eventIDs
mydf
#     ID TimeStamp VAR1 eventIDs
#1    84  09:31:12 2978        1
#2    84  09:31:12 2625        1
#3    84  09:31:12 2088        1
#4    84  09:31:12 1716        1
#5    84  09:31:12 2254        1
#6  -999      <NA> 1632        3
#7  -999      <NA> 1731        3
#8  -999      <NA> 2648        3
#9    88  09:45:31 1625        2
#10   88  09:45:31 2798        2
#11   88  09:45:31 1366        2
#12   88  09:45:31 1245        2
#13   88  09:45:31 1291        2
#14   88  09:45:31 2801        2
#15   88  09:45:31 2746        2
#16 -999      <NA> 1411        3
#17 -999      <NA> 1738        3
#18 -999      <NA> 1398        3
#19 -999      <NA> 1918        3
#20 -999      <NA> 1575        3

数据中的ID变量表示牛/无牛事件。 -999是在ID == NA时确定的。 TimeStamp代表挤奶的开始。此变量用于标识eventIDs变量。这很重要,因为在一天中奶牛可以挤奶多次。这就是为什么它是为了分离每头牛的每个挤奶事件而创建的原因。 VAR1表示正在调查的任何变量。

所需输出

每次挤奶和每次挤奶都需要VAR1的平均值。目前,这是我的输出:

(res1 <- aggregate(mydf[,"VAR1"],
                   by = list(ID = mydf[,"ID"], eventIDs = mydf[,"eventIDs"]),
                   FUN = mean))
#    ID eventIDs        x
#1   84        1 2332.200
#2   88        2 1981.714
#3 -999        3 1756.375

这是显而易见的结果,因为没有指示变量将每个连续的“非挤奶”分开。事件。事实上我想这样:

meanVAR1 <- c((2978+2625+2088+1716+2254)/5,
              (1632+1731+2648)/3,
              (1625+2798+1366+1245+1291+2801+2746)/7,
              (1411+1738+1398+1918+1575)/5) 
eventIDs <- c(1,3,2,3) 
(res2 <- data.frame(ID = ID1, meanVAR1 = meanVAR1, eventIDs = eventIDs))
#    ID meanVAR1 eventIDs
#1   84 2332.200        1
#2 -999 2003.667        3
#3   88 1981.714        2
#4 -999 1608.000        3

有什么建议吗?

2 个答案:

答案 0 :(得分:2)

假设您的数据按时间顺序按照示例进行排序。使用rle可以很容易地为每个事件创建唯一的代理ID:

mydf$ID2 = rep(1:length(rle(mydf$ID)$lengths),times=rle(mydf$ID)$lengths)

然后与aggregate或我的示例data.table一起使用此新ID可帮助我们获得所需的结果:

setDT(mydf)[,list(meanVar1=mean(VAR1)),by=c("ID","ID2","eventIDs")]
   #       ID ID2 eventIDs meanVar1
   # 1:   84 1   1        1 2332.200
   # 2: -999 2   2        3 2003.667
   # 3:   88 3   3        2 1981.714
   # 4: -999 4   4        3 1608.000

答案 1 :(得分:2)

使用devel version of data.table v1.9.5实现新功能rleid()以在这些情况下使用:

require(data.table) # v1.9.5+
ans = setDT(mydf)[, .(meanVAR1 = mean(VAR1)), by=.(ID, eventIDs, rleid(ID))]    
#      ID eventIDs rleid meanVAR1
# 1:   84        1     1 2332.200
# 2: -999        3     2 2003.667
# 3:   88        2     3 1981.714
# 4: -999        3     4 1608.000

如果您不想要rleid列,可以执行以下操作将其删除:

ans[, rleid := NULL]

查看HTML vignettes了解详情。