2017-07-26 59 views
0

我有數據幀mydata如下基於另一列的條件,柱除了在,使用R

ID TS  TB TC 
    1 1.7360  -1 0 
    2 1.7302  -1 0.254 
    3 1.7244  0 0.624 
    4 1.7232  0 0.254 
    5 1.7208  0 1.25 
    6 1.7208  0 0 
    7 1.7208  0 0 
    8 1.7023  0 0 
    9 1.6814  0 0 
10 1.6768  1 0 
11 1.6746  0 6.25 
12 1.6503  0 0.2547 
13 1.6258  0 0.987 
14 1.6190  0 0.3654 
15 1.6154  0 0.6251 
16 1.6258  0 0.369 
17 1.6397  0 0 
18 1.6443  0 0 
19 1.6491  0 0 
20 1.6503  0 0 

現在我需要加/減的值的TS and TC和帶條件創建另一個新列TSC,如果存在那麼TSC == TS + TCTB-1直到有另一+1 or -1TB,否則,如果存在則TSC == TS - TCTB1,直到有另一+1 or -1TB。在B列然後Tsc == TS +TC列的數據幀開始時也有可能存在0

下面是我的最終結果

ID  TS  TB  TC  TSC 
1 1.73602  -1 0  1.736020823 
2 1.73023  -1 0.254 1.984238239 
3 1.72445  0 0.624 2.348455656 
4 1.72326  0 0.254 1.977269484 
5 1.72089  0 1.25 2.970897142 
6 1.72089  0 0  1.720897142 
7 1.72089  0 0  1.720897142 
8 1.70236  0 0  1.70236322 
9 1.68145  0 0  1.681456955 
10 1.67686  1 0  1.676860542 
11 1.67463  0 6.25 4.575363528 
12 1.65031  0 0.2547 1.395619965 
13 1.62585  0 0.987 0.638855188 
14 1.61903  0 0.3654 1.253634704 
15 1.61547  0 0.6251 0.990376191 
16 1.62585  0 0.369 1.256855188 
17 1.63979  0 0  1.639792697 
18 1.64438  0 0  1.64438911 
19 1.64913  0 0  1.649133794 
20 1.65031  0 0  1.650319965 
+0

線15看起來像TSC = TC - TS,而不是TS - TC - 是一個錯字或其他一些行爲? – Spacedman

+0

@akrun你的解決方案只是增加值,但它不會減去'B == 1' – SBS

+1

@akrun我不認爲這是行得通的 - 我認爲OP希望第10到20行被減去,因爲TB列切換+/-操作。是? – Spacedman

回答

1

通過構建+1的矢量添加和-1減去其容易。那麼我們如何構建呢?

首先構造一個矢量,用前一個非零替換所有的零。通過使用rle,我們可以構造一個向量,出現次數爲-1,1或0,然後用前一個非零值替換零,然後反轉並僅獲得1和-1的向量。

棒-1就開始滿足「如果與零開始,減去」條件:

> rx = rle(c(-1,mydata$TB)) 

現在看到的是零:

> wz = which(rx$values==0) 

設置零到任何以前的值是。

> rx$values[wz]=rx$values[wz-1] 

現在擴展到1和-1的矢量,切斷第一個擺脫我們開始的-1。此外,使其+1添加和-1減去:

> mydata$TBop = -inverse.rle(rx)[-1] 

然後執行操作:

> mydata$TSC=mydata$TS + mydata$TBop*mydata$TC 
> mydata 
    ID  TS TB  TC TBop  TSC 
1: 1 1.7360 -1 0.0000 1 1.7360 
2: 2 1.7302 -1 0.2540 1 1.9842 
3: 3 1.7244 0 0.6240 1 2.3484 
4: 4 1.7232 0 0.2540 1 1.9772 
5: 5 1.7208 0 1.2500 1 2.9708 
6: 6 1.7208 0 0.0000 1 1.7208 
7: 7 1.7208 0 0.0000 1 1.7208 
8: 8 1.7023 0 0.0000 1 1.7023 
9: 9 1.6814 0 0.0000 1 1.6814 
10: 10 1.6768 1 0.0000 -1 1.6768 
11: 11 1.6746 0 6.2500 -1 -4.5754 
12: 12 1.6503 0 0.2547 -1 1.3956 
13: 13 1.6258 0 0.9870 -1 0.6388 
14: 14 1.6190 0 0.3654 -1 1.2536 
15: 15 1.6154 0 0.6251 -1 0.9903 
16: 16 1.6258 0 0.3690 -1 1.2568 
17: 17 1.6397 0 0.0000 -1 1.6397 
18: 18 1.6443 0 0.0000 -1 1.6443 
19: 19 1.6491 0 0.0000 -1 1.6491 
20: 20 1.6503 0 0.0000 -1 1.6503 

可能是最好的寫操作可測試功能:

Top <- 
function(x){ 
rx = rle(c(-1,x)) 
wz = which(rx$values==0) 
rx$values[wz] = rx$values[wz-1] 
-inverse.rle(rx)[-1] 
} 

然後你可以檢查簡單的例子:

> Top(0) # add 
[1] 1 
> Top(-1) # add 
[1] 1 
> Top(1) # subtract 
[1] -1 

> Top(c(0,-1,1,-1,0,0,0)) 
[1] 1 1 -1 1 1 1 1 # add, add, sub, add, add, add, add 

> Top(mydata$TB) 
[1] 1 1 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 

那麼你的解決方案是一個班輪:在您的輸出

> mydata$TSC = mydata$TS + Top(mydata$TB) * mydata$TC