我有一个带有两个布尔列A和B的data.table。我想添加一个新的布尔行C,它依赖于A和B,但是我遇到了麻烦' look& #39;在之前和上升的行中。
我想按如下方式定义C.如果有一个A = 1的行,并且在三行的范围内至少有一个B = 1那么我希望C在所有的A = 1和C = 0的行上变成C = 1范围内的其他行。否则C应为C = B.
在两个范围重叠并且两者都包含B = 1的情况下,C在两个行上应该变为C = 1,其中A = 1且C = 0。有关更多说明:
df <- data.table(A=c(0,0,0,1,0,0,0,0,0,0,0,1,1,0,0),
B=c(0,1,0,0,0,1,0,1,1,0,0,0,0,0,1))
A B A B C
1: 0 0 # 1: 0 0 0
2: 0 1 # 2: 0 1 0
3: 0 0 # 3: 0 0 0
4: 1 0 # range of three 4: 1 0 1
5: 0 0 # 5: 0 0 0
6: 0 1 # 6: 0 1 0
7: 0 0 # 7: 0 0 0
8: 0 1 8: 0 1 1 # C = B
9: 0 1 # 9: 0 1 0
10: 0 0 ## 10: 0 0 0
11: 0 0 ## 11: 0 0 0
12: 1 0 ## overlapping range of three 12: 1 0 1
13: 1 0 ## 13: 1 0 1
14: 0 0 ## 14: 0 0 0
15: 0 1 ## 15: 0 1 0
我该如何做到这一点,我对这一点毫无头绪。
答案 0 :(得分:3)
# Find ranges where A == 1
ind <- lapply(which(df$A == 1)
, function(i){s <- i + -3:3; s[s %in% seq(nrow(df))]})
# Remove ranges with no B == 1
good <- sapply(ind, function(i) df[i, any(B == 1)])
ind <- unique(unlist(ind[good]))
# Assign C as described
df[, C := B]
df[ind, C := as.numeric(A == 1)]
df
# A B C
# 1: 0 0 0
# 2: 0 1 0
# 3: 0 0 0
# 4: 1 0 1
# 5: 0 0 0
# 6: 0 1 0
# 7: 0 0 0
# 8: 0 1 1
# 9: 0 1 0
# 10: 0 0 0
# 11: 0 0 0
# 12: 1 0 1
# 13: 1 0 1
# 14: 0 0 0
# 15: 0 1 0
以下使用的数据。我更改了您的df
定义以匹配显示的df
df <- data.table(A=c(0,0,0,1,0,0,0,0,0,0,0,0,1,0,0),
B=c(0,1,0,0,0,1,0,1,1,0,0,0,0,0,0))
df[12, A := 1]
df[15, B := 1]
df
# A B
# 1: 0 0
# 2: 0 1
# 3: 0 0
# 4: 1 0
# 5: 0 0
# 6: 0 1
# 7: 0 0
# 8: 0 1
# 9: 0 1
# 10: 0 0
# 11: 0 0
# 12: 1 0
# 13: 1 0
# 14: 0 0
# 15: 0 1
答案 1 :(得分:2)
这是一个基于tidyverse套件的解决方案:
我定义了2个临时变量 - A1
确定{row 1:row + 3}窗口中的A = 1
是否在任何位置。 C1
会在窗口的任何位置测试A = 1
和B = 1
。
library(tidyverse)
df %>%
mutate(
A1 = (cumsum(lead(A, 3, default = 0)) - cumsum(dplyr::lag(A, 4, default = 0)) > 0),
C1 = (A & dplyr::lead(cumsum(B), n = 3, default = 0) - dplyr::lag(cumsum(B), n = 4, default = 0)) * 1,
C = ifelse(!A1, B, C1)
) %>%
select(-A1, -C1)