分离单个事件的方法
Way to separate out individual events
我有一个大型数据集,每 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
变量表示cow/no-cow事件。 -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
这是显而易见的结果,因为没有指示变量来分隔每个连续的 'non-milking' 事件。事实上我想要这样:
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
有什么建议吗?
假设您的数据按照您的示例中的时间顺序排序。使用 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
使用 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 以了解更多信息。
我有一个大型数据集,每 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
变量表示cow/no-cow事件。 -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
这是显而易见的结果,因为没有指示变量来分隔每个连续的 'non-milking' 事件。事实上我想要这样:
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
有什么建议吗?
假设您的数据按照您的示例中的时间顺序排序。使用 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
使用 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 以了解更多信息。