我有一个由5个变量(括号中的类)组成的值的数据框架。
1) DateTime (as.POSIXct),2) ID (字符),3)传感器1(数字),4)传感器2(数字),5)传感器3(数字)
这一数据是从5条有标记的鱼中收集的。每个鱼都有一个标签,上面有3个传感器,每个传感器都有一个唯一的ID (因此5个鱼乘以3个ID/ tag =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循环来提取显示正确顺序的数据行,并将这些行放入一个新的数据框架中。我不知道如何让R将我的标准理解为一个条件语句,以及在执行我希望循环做的事情之前,如何满足来自3个不同观察的条件。如果可能的话,我很乐意用其他方式来做,而不是使用循环。下面是我的循环的一个例子(我知道我不是调用一个真值或假值来测试==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))
}
}发布于 2015-06-08 18:17:12
您的问题归结为在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您现在可以进行任何要进一步过滤信息的计算(例如,删除测量之间时间差太大的周期)。
https://stackoverflow.com/questions/30715722
复制相似问题