观察在组内的列中的位置

时间:2017-01-25 17:52:24

标签: r data.table

我的部分数据如下:

    group       value
 1:     a  0.00000000
 2:     a  0.00000000
 3:     a -0.18586657
 4:     b -1.71540591
 5:     b  0.11086867
 6:     b -0.14350153
 7:     b  0.93055422
 8:     c  0.00000000
 9:     c  0.00000000
10:     c -0.03173145

library(data.table)
DT = setDT(structure(list(group = c("a", "a", "a", "b", "b", "b", "b", "c", 
"c", "c"), value = c(0, 0, -0.18586657, -1.71540591, 0.11086867, 
-0.14350153, 0.93055422, 0, 0, -0.03173145)), .Names = c("group", 
"value"), row.names = c(NA, -10L), class = "data.frame"))

对于每个组,我想创建一个新的虚拟变量。如果虚拟变量的对应值(第2列的变量)在它之前有两个零并且本身非零,则该虚拟变量等于1,否则它等于0.

我尝试了很多方法,但无法理解。

1 个答案:

答案 0 :(得分:0)

您可以使用shift函数和两个&来连接三个逻辑语句,然后使用by参数逐组分组。请注意,shift的默认值是滞后,这就是我们想要的。

df[, value2:= as.integer(value != 0 & shift(value) == 0 & shift(value, n=2) == 0), by=group]
df
    group       value value2
 1:     a  0.00000000      0
 2:     a  0.00000000      0
 3:     a -0.18586657      1
 4:     b -1.71540591     NA
 5:     b  0.11086867      0
 6:     b -0.14350153      0
 7:     b  0.93055422      0
 8:     c  0.00000000      0
 9:     c  0.00000000      0
10:     c -0.03173145      1

要填写组中第一个值为非零的任何NA,您可以将结果链接起来。

df[, value2:= as.integer(value != 0 & shift(value) == 0 & shift(value, n=2) == 0), by=group
   ][is.na(value2), value2:= 0]
df
    group       value value2
 1:     a  0.00000000      0
 2:     a  0.00000000      0
 3:     a -0.18586657      1
 4:     b -1.71540591      0
 5:     b  0.11086867      0
 6:     b -0.14350153      0
 7:     b  0.93055422      0
 8:     c  0.00000000      0
 9:     c  0.00000000      0
10:     c -0.03173145      1

这里,第二个链子集在NA值上,并用0替换它们。

正如@Frank在评论中提到的那样,shift可以接受其n个参数的向量。使用此方法而不是两次调用shift的方法是

df[, as.integer(value != 0 & min(unlist(shift(value, n=1:2)) == 0, na.rm=TRUE)), by=group]

与先前版本不同,不会产生新闻。