2015-04-23 61 views
2

我試圖根據分組中的另一列中的條件替換列中的某些行值。使用'by'替換data.table中的行值並且條件

編輯:編輯以突出顯示問題的遞歸性質。

E.g.

DT = data.table(y=rep(c(1,3), each = 3) 
      ,v=as.numeric(c(1,2,4,4,5,8)) 
      ,x=as.numeric(rep(c(9:11),each=2)),key=c("y","v")) 
DT 
    y v x 
1: 1 1 9 
2: 1 2 9 
3: 1 4 10 
4: 3 4 10 
5: 3 5 11 
6: 3 8 11 

在每個「Y」,然後,我想要替換的「X」,其中「V」具有觀察V + T(例如,T = 3),值用2222(或在現實的結果功能)以下結果:

y v x 
1: 1 1 9 
2: 1 2 9 
3: 1 4 2222 
4: 3 4 10 
5: 3 5 11 
6: 3 8 2222 

我試過以下,但無濟於事。

DT[which((v-3) %in% v), x:= 2222, y][] 

而且它神祕的結果(?):

y v x 
1: 1 1 9 
2: 1 2 9 
3: 1 4 2222 
4: 3 4 2222 
5: 3 5 2222 
6: 3 8 2222 

運行:

DT[,print(which((v-3) %in% v)), by =y] 

表明它在組內的正確索引,但是從什麼發生(或缺乏)我不明白。

回答

5

你可以嘗試使用replace(其中可能有一些開銷,因爲它拷貝整個x

DT[, x:=replace(x, which(v %in% (v+3)), 2222), by=y] 
# y v x 
#1: 1 1 9 
#2: 1 2 9 
#3: 1 4 2222 
#4: 3 4 10 
#5: 3 5 11 
#6: 3 8 2222 

或者,你可以創建一個邏輯索引列,然後做下一步

DT[,indx:=v %in% (v+3), by=y][(indx), x:=2222, by=y][, indx:=NULL] 
DT 
# y v x 
#1: 1 1 9 
#2: 1 2 9 
#3: 1 4 2222 
#4: 3 4 10 
#5: 3 5 11 
#6: 3 8 2222 
分配

或略有修改,以創建一個索引

使用 .I你自己的方法
+0

感謝您的建議!它確實奏效,但我意識到我的例子很簡單,並沒有真正理解我的問題的本質,所以我相應地編輯了它。順便說一句,L做什麼?我似乎無法理解它的目的。 –

+0

@EndreGrünerOfstad我不知道它在哪裏被記錄,但'10L'是整數,而'10'是一個浮點數(因此可能會被計算機四捨五入導致意外的結果)。在這種情況下,它應該沒關係,因爲'v'已經是一個浮點列。 – Frank

+0

@EndreGrünerOfstad我使用'10L'作爲'v'的類是整數,當類不匹配時data.table將拋出警告/錯誤。如果它是數字,它將只是'10'。 – akrun