为什么在ifelse函数中使用AND陈述错误的结果

时间:2019-06-06 14:05:22

标签: r if-statement lag

我有以下数据集:

df1 <- data.frame(number = c(1,1,0,0,0,0,0,1,1))

在此数据集中,我想创建第二列,该列显示在第一列和第二个滞后等于0且第一个前导等于1时是否存在情况。一个情况,因此将数字1放在发生从0到1的变化的第二列中(如果不是,则等于44。因此,在此输出中,第二列中的所有行都应等于44,但第8行除外)

这是我的代码。在下面的评论中,我将贴上所需结果的照片。

df1$t<-ifelse(df1[,1]==1 & lag(df1[,1]==0,1,default = 44) & lag(df1[,1]==0,2,default = 44)
                              & lead(df1[,1]==1,1,default = 44)
                              ,1,44)

1 个答案:

答案 0 :(得分:0)

尽管OP要求解释为什么他的代码未返回预期结果(由Gregor's comment解决),但我想提出一种替代方法。

如果我理解正确,那么OP希望在df1$number中找到所有子序列,这些子序列由两个零后跟两个1,即c(0, 0, 1, 1)组成。然后,在子序列中包含第一个行的行应用1标记,而所有其他行应将44作为默认值。

data.table的v1.12.0版(于CRAN 13 Jan 2019)开始,shift()函数可识别负滞后/超前参数。这样,一列就可以移动多个值。满足上述条件的行号由后续的联接操作标识。最后,df1使用以下行号进行选择性更新:

# use enhanced sample dataset, rows 10 to 21 added
df1 <- data.frame(number = c(1,1,0,0,0,0,0,1,1,0,1,0,1,1,0,0,1,0,0,1,1))

library(data.table)
setDT(df1)[, t := 44] # coerce to data.table, pre-populate result column
# shift and join
idx <- df1[, shift(number, 2:-1)][.(0, 0, 1, 1), on = paste0("V", 1:4), which = TRUE]
df1[idx, t := 1] # selective update
df1
    number  t
 1:      1 44
 2:      1 44
 3:      0 44
 4:      0 44
 5:      0 44
 6:      0 44
 7:      0 44
 8:      1  1
 9:      1 44
10:      0 44
11:      1 44
12:      0 44
13:      1 44
14:      1 44
15:      0 44
16:      0 44
17:      1 44
18:      0 44
19:      0 44
20:      1  1
21:      1 44
    number  t

从本质上讲,通过移动并与期望值进行比较,这可以作为OP的方法。但是,OP的方法需要对四个比较和三个移位操作进行编码,而此处的移位是一步完成的,而所有列的比较是同时由第二步的联接操作完成的。

其他说明

移位操作

df1[, shift(number, 2:-1)]

返回

    V1 V2 V3 V4
 1: NA NA  1  1
 2: NA  1  1  0
 3:  1  1  0  0
 4:  1  0  0  0
 5:  0  0  0  0
 6:  0  0  0  0
 7:  0  0  0  1
 8:  0  0  1  1
 9:  0  1  1  0
10:  1  1  0  1
11:  1  0  1  0
12:  0  1  0  1
13:  1  0  1  1
14:  0  1  1  0
15:  1  1  0  0
16:  1  0  0  1
17:  0  0  1  0
18:  0  1  0  0
19:  1  0  0  1
20:  0  0  1  1
21:  0  1  1 NA
    V1 V2 V3 V4

在随后的加入操作中,

df1[, shift(number, 2:-1)][.(0, 0, 1, 1), on = paste0("V", 1:4), which = TRUE]

which = TRUE仅要求返回匹配行的索引,

[1]  8 20