我有一个大的数据集,每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
有什么建议吗?
答案 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了解详情。