2015-06-08 58 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 

你現在可以做你想做的進一步過濾信息(任何計算如去除週期,其中的測量之間的時間差過大)。