我有一个由5个变量组成的数据框(括号中的类)
1)DateTime(as.POSIXct),2)ID(字符),3)传感器1(数字),4)传感器2(数字),5)传感器3(数字)
该数据来自5条标记鱼类。每条鱼都有一个带有3个传感器的标签,每个传感器都有一个唯一的ID(因此5个鱼3个ID /标签= 15个唯一ID)。传感器记录彼此相关的测量值,因此同时记录这些测量值。每次以相同的顺序发送测量数据(ID = A,然后是B,然后是C)。该数据被发送到只能一次接收一个传输的监听接收器。为避免多个标签同时发送数据并且可能永远不会接收数据,每个传感器在收集一组新测量值并重新开始循环之前以随机间隔(2-4分钟)发送出去。但是对于随机间隔,有时多个标签会尝试同时发送数据,因此不会记录这些测量值。以下为一条鱼提供了示例数据:
> head(dat,15)
DateTime ID Sensor1 Sensor2 Sensor3
446 2015-05-15 19:05:41 B NA 10.2 NA
464 2015-05-15 19:14:20 B NA 10.2 NA
475 2015-05-15 19:17:32 C NA NA 10.58824
486 2015-05-15 19:19:52 A 1.999499 NA NA
499 2015-05-15 19:22:31 B NA 10.2 NA
515 2015-05-15 19:28:10 A 1.999499 NA NA
523 2015-05-15 19:30:56 B NA 10.1 NA
542 2015-05-15 19:37:22 A 1.999499 NA NA
559 2015-05-15 19:41:09 B NA 10.2 NA
574 2015-05-15 19:44:47 C NA NA 10.50980
613 2015-05-15 19:50:23 B NA 10.3 NA
633 2015-05-15 19:53:07 C NA NA 10.50980
650 2015-05-15 19:56:32 A 1.999499 NA NA
684 2015-05-15 20:02:49 C NA NA 10.50980
702 2015-05-15 20:05:51 A 1.999499 NA NA
我的问题是尝试仅提取完整的数据集,这意味着从同一周期检测到标签的ID A,B和C的周期,因此来自3个传感器的数据可以一起使用。如果在一个循环中错过了ID,那么我不希望该循环中的任何测量。在上面的示例中,我只想保留一个循环(以数字542,559和574开头的行。)
一旦我删除了所有不完整的循环,我想将每个循环组合成一个单独的观察,因此我有一个新的数据框,其中每一行代表一个循环,所有3个传感器变量都有值。计算ID A和C之间的时间也是有用的,这样我就可以验证它们来自同一个周期,而不是连续多次错过相同ID的情况,但订单仍然有效(机会)发生的事情非常非常低。)
到目前为止,我一直在尝试使用for循环来提取看到正确顺序的dat行,并将这些行放入新的数据框中。我不确定如何让R作为条件语句读取我的标准,以及如何在执行我想要循环的操作之前满足3个不同观察的标准。如果可能的话,我会很乐意以除了使用循环之外的方式来做。下面是我的循环示例(我知道我没有调用True或False值来测试== TRUE条件,我只是不确定如何为每一行执行此操作):
#make blank dataframe
output <- data.frame (DateTime=rep(as.POSIXct(NA, tz="UTC"), length(tag123o$Transmitter)),
ID=rep(as.character(NA), length(tag123o$Transmitter)),
Sensor1=rep(as.numeric(NA), length(tag123o$Transmitter)),
Sensor2=rep(as.numeric(NA), length(tag123o$Transmitter)),
Sensor3=rep(as.numeric(NA), length(tag123o$Transmitter)))
for (i in 1:length(dat$ID)) {
if (((dat[i,names(dat)=="ID"] == "A69-1105-123") &
(dat[i+1,names(dat)=="ID"] == "A69-1105-124") &
(dat[i+2,names(dat)=="ID"] == "A69-1105-125"))==TRUE) {
output[i,] <- cbind(dat[i,], data.frame(Cycle=i))
output[i+1,] <- cbind(dat[i+1,], data.frame (Cycle=i))
output[i+2,] <- cbind(dat[i+2,], data.frame(Cycle=i))
}
}
答案 0 :(得分:3)
您的问题可归结为在ID序列中搜索“ABC”序列:
(matches <- gregexpr("ABC", paste(dat$ID, collapse=""))[[1]])
# [1] 8
# ...
这表示唯一匹配从第8行开始。您现在知道Sensor1的信息位于编号为matches
的行中,Sensor2的信息位于编号为matches+1
的行中,并且信息为Sensor3位于编号为matches+2
的行中。这使您能够有效地构建组合循环信息的所需数据框:
data.frame(DateTime1 = dat$DateTime[matches],
DateTime2 = dat$DateTime[matches+1],
DateTime3 = dat$DateTime[matches+2],
Sensor1 = dat$Sensor1[matches],
Sensor2 = dat$Sensor2[matches+1],
Sensor3 = dat$Sensor3[matches+2])
# DateTime1 DateTime2 DateTime3 Sensor1 Sensor2 Sensor3
# 1 2015-05-15 19:37:22 2015-05-15 19:41:09 2015-05-15 19:44:47 1.999499 10.2 10.5098
您现在可以进行任何想要进一步过滤信息的计算(例如,删除测量之间的时差过大的周期)。