2016-11-25 35 views
1

我在R.Customly計算列之間的偏差中的R

一個新手

我試圖計算列之間的偏差,並期望應用幾個規則:

  1. 差由電流值減去計算前值
  2. 如果當前值是NA,則返回NA不計算
  3. 如果以前的值是NA,則電流值減去前值前值,直至減有效值
  4. 在第一列中的值始終是有效

例如:

start = c(1, 2, 3, 4) 
a = c(2, NA, 5, 6) 
b = c(4, 5, NA, 8) 

test <- data.frame(start, a, b) 
test 
    start a b 
1  1 2 4 
2  2 NA 5 
3  3 5 NA 
4  4 6 8 

預期:

result 

    a_delta b_delta 
1  1  2 
2  NA  3 
3  2  NA 
4  2  2 

注:

  1. 細胞(2,1)結果是NA,因爲在測試中的單元(2,2)是NA
  2. 細胞(2,2)中的結果是3,因爲單元(2,3)減去細胞(2,1)的結果得到3

這是我的斷碼。任何建議都歡迎:

f <- function(data){ 
    cn <- colnames(data) 
    cl <- ncol(data) 
    for (i in 2:cl)){ 
    if (is.na(data$i)) {a <- NA} 
    else if (!is.na(data$(i-1))) {paste(cn[i], "_delta") <- data$cn[i] - data$cn[i-1]} 
    else { # check if previous value is NA repeatively 
     t < i - 1 
     while (is.na(data$cn[t])) { 
     t <- t - 1 
     } 
     paste(cn[i], "_delta") <- data$cn[i] - data$cn[t] 
    } 
    } 

} 

f(test) 

回答

0

主要功能:

CalcDev <- function(x){ 
    x <- unlist(x) 
    if (!any(is.na(x))){ 
    return(diff(x, 1)) 
    } else { 
    tmp <- x[-1] 
    res <- diff(na.omit(x), 1) 
    tmp[!is.na(tmp)] <- res 
    return(tmp) 
    } 
} 

以及如何使用:

start = c(1, 2, 3, 4) 
a = c(2, NA, 5, 6) 
b = c(4, 5, NA, 8) 
test <- data.frame(start, a, b) 
plyr::adply(test, 1, CalcDev)[, -1] 

結果:

a b 
1 1 2 
2 NA 3 
3 2 NA 
4 2 2 

你只需重命名列。

我無法運行你的代碼,所以沒有基準。

編輯: 回答您的意見,您可以使用CalcDev功能dplyr鏈,如果你vecorize它:

CalcDev.Vect <- Vectorize(CalcDev) 

test %>% 
    CalcDev.Vect %>% 
    .[, -1] %>% 
    as.data.frame 

你會得到類似的結果,而且會快很多,尤其是對大數據集。

有兩種選擇:直接在do({})adply內使用CalcDev,但兩者都會是較慢的解決方案。 基準小型數據集:

    expr  min  lq mean median  uq  max neval cld 
      foo.plyr(test) 2240.34 2392.08 2511.3 2490.13 2577.32 3199.16 100 b 
     foo.do_dplyr(test) 2680.34 2933.70 3104.4 3015.15 3109.48 5771.83 100 d 
foo.plyr_in_dplyr(test) 2471.51 2635.04 2805.7 2702.99 2802.29 9422.46 100 c 
      foo.Vect(test) 441.55 490.58 539.7 539.92 564.74 928.41 100 a 

而對於更大的數據集的評估時間差將更加激烈。

+0

謝謝@Andrey Kolyadin,效果很好。一個側面的問題,在dplyr中是否有類似plyr :: adply的函數? – wctjerry