2015-06-08 63 views
4

成套我有(括号类)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)) 
      } 
    } 

回答

3

你的问题归结为ID的序列中搜索“ABC”的序列:

(matches <- gregexpr("ABC", paste(dat$ID, collapse=""))[[1]]) 
# [1] 8 
# ... 

这表明,只有比赛在8行开始你现在知道了传感器1的信息,在行编号为matches,传感器2的信息在行编号为matches+1,而传感器3的信息在编号为的行。这使您能够高效地构建,结合循环信息所需的数据帧:

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 

你现在可以做你想做的进一步过滤信息(任何计算如去除周期,其中的测量之间的时间差过大)。