2011-08-18 83 views
5

我是一個相對R noob。Conditioned Moving Max

我有一個大的數據集,看起來是這樣的:

  Tempadjvolt  newmass  rgdeltas 
2794  498.5777 0.5355647187 0.00000000 
2795  499.7577 0.5355647187 0.00000000 
2796  500.7877 0.3415104788 -2.87487763 
2797  502.1177 0.4312854788 -1.54487763 
2798  500.3877 0.5355647187 0.00000000 
2799  502.5377 0.4596354788 -1.12487763 
2800  507.6877 0.8072604788 4.02512237 
2801  505.2577 0.6432354788 1.59512237 
2802  505.7977 0.6796854788 2.13512237 
2803  517.8877 1.4957604788 14.22512237 
2804  502.2477 0.4400604788 -1.41487763 
2805  507.3677 0.7856604788 3.70512237 
2806  519.7277 1.6199604788 16.06512237 
2807  528.9377 2.2416354788 25.27512237 
2808  520.2677 1.6564104788 16.60512237 
2809  519.3877 0.5355647187 0.00000000 
2810  526.5677 2.0816604788 22.90512237 
2811  519.5377 0.5355647187 0.00000000 
2812  526.9277 2.1059604788 23.26512237 
2813  529.9877 2.3125104788 26.32512237 
2814  514.4077 1.2608604788 10.74512237 
2815  518.3777 1.5288354788 14.71512237 

我試圖找出負rgdeltas值[例如,聯排2804]再「看」後面7位,領先找到最高的Tempadjvolt並將行2804的tempadjvolt設置爲該本地最大值。

幀長〜4000行,其中〜515爲負值。我嘗試了一些循環,可以運行...但也吐出了一大堆新手 - 這讓我覺得他們很糟糕/構造不當。

任何援助將不勝感激。

正如評論中指出的那樣,原帖不明。我不關心連續的負rgdeltas值。對於幀的前端和後端7內的負值,理想情況下,循環將在開始/結束之前向前和向後看起來多個位置。在這一點上不太關心這一點。

更多一點背景: 這是最初用C#編寫的信號處理程序的一部分,我試圖移動到R以增強對環境監視器輸出的大量文件輸出的一些更容易的批處理。我沒有寫出原始代碼,這只是一大堆事情中的一小部分。

我很感激幫助。謝謝!

+0

我不認爲這個問題有一個明確的答案。如果兩個負值在彼此的14個位置之內,您沒有提供解決方案,因爲它們在某些情況下很明顯。 (......或者我誤解了重置爲「基準」的想法 –

+0

你也沒有具體說明如果負值小於7行開頭或結尾應該發生什麼,我懷疑這可能是你的新手協議 – joran

+0

Dwin,joran - 謝謝,上面提到我的數據很差,我正在解決這個問題,我並不關心對方的兩個或更多的負面因素。如果價值在開始或結束......我沒有想過。對歧義的道歉,希望我的編輯在一分鐘內將有所幫助。 –

回答

4

假設它的名字是dat

negidxs <- as.numeric(rownames(dat)[ dat[[3]] < 0 ]) 
for (i in negidxs){ 
     dat[as.character(i), "Tempadjvolt"] <- 
      max(dat[rownames(dat) %in% (i-7):(i+7), "Tempadjvolt"], na.rm=TRUE) } 
dat 
    #----------------------------------# 
    Tempadjvolt newmass rgdeltas 
2794 498.5777 0.5355647 0.000000 
2795 499.7577 0.5355647 0.000000 
2796 517.8877 0.3415105 -2.874878 
2797 517.8877 0.4312855 -1.544878 
2798 500.3877 0.5355647 0.000000 
2799 519.7277 0.4596355 -1.124878 
2800 507.6877 0.8072605 4.025122 
2801 505.2577 0.6432355 1.595122 
2802 505.7977 0.6796855 2.135122 
#snipped----- 
5

1)填零。假設數據幀稱爲DF我們使用rollapply在動物園包應用功能,f,向寬度15移動窗口:在上面我們填充附近開始時的點

library(zoo) 
# columns of DF are (1) Tempadjvolt, (2) newmass and (3) rgdeltas 
f <- function(x) if (x[8, 3] < 0) max(x[, 1]) else x[8, 1] 
DF[[1]] <- rollapply(DF, 15, f, fill = 0, by.column = FALSE) 

和用零結束因爲處理這個問題的確切方法似乎並不重要,但我們可以使用其他填充值。

2)保留最終值。另一種可能性是隻處理未在端部附近的點:

DF[seq(8, nrow(DF)-7), 1] <- rollapply(DF, 15, f, by.column = FALSE) 

3)局部模板。或者我們也可以使用partial = TRUE再取附近像這樣兩端的部分值的max

f2 <- function(x) { 
     # Columns of DF2 are (1) Tempadjvolt, (2) newmass, (3) rgdeltas and (4) seq. 
     # Condition is TRUE if passed a partial x near the beginning. 
     # k is row index of current row in x. Normally 8 but near start it varies. 
     k <- if (x[1, 4] == 1) nrow(x) - 7 else 8 
     if (x[k, 3] < 0) max(x[, 1]) else x[k, 1] 
} 
DF2 <- cbind(DF, seq = 1:nrow(DF)) 
DF[[1]] <- rollapply(DF2, 15, f2, partial = TRUE, by.column = FALSE)