2015-04-23 63 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