** 鉴于 OP 要求状态逻辑/策略的进一步编辑**
实际上,您的条件是三个条件的组合。如果我们创建四个区域,就像我在上图中创建的那样,并将这些区域命名为 1 到 4
1 where q values are >= z
2 where q values are >= i
3 where q values are >= s
4 where q values are < s
现在,条件可以翻译为
-
TRUE 在 2 区和 3 区时
- 但是如果从这些
TRUE区域退出一次,只有到达zone 3时才会变为TRUE
- 此外,如果它已命中
zone 4,则只有在它到达/命中zone 1 时,它才能变为TRUE,至少一次。
策略
- 为了整合这些,我使用了 tidyverse 管道语法
-
- 首先将各个区域中的所有值相除(比如
q1)
-
- 作为第一个条件,在
TRUE 中划分区域 2 和 3,在 `FALSE 中划分其他区域
-
- 作为第二个条件,比如
c2,即是否从区域 4 退出并到达区域 1,将区域 4 标记为 F,将区域 1 标记为 T,其余全部为 NA。
- 第一个值可以是
NA,因此如果不适用,则将第一个值替换为 c1
-
- 作为最后一个条件说
c3,即到达区域 3 时为 TRUE,将 3 标记为TRUE 1 和 4 标记为FALSE 并将区域 2 保留为NA 以便稍后检查它是否从哪个到达这里区。
- 第一个值可以是
NA,因此如果不适用,则将第一个值替换为FALSE
- 现在只剩下工作来填补
c2 和c3 的NA。使用 zoo::na.locf 或 tidyr::fill 填充所有 NA 将持续可用值。
- 您最终想要的结果是所有条件的组合,所以
c1 & c2 & c3
q = c(0.00000000, -0.70218526, -0.60635393, 0.32325554, -0.45921704, -0.57336113, -0.77683717,
-1.76347868, -1.90884891, -0.86157465, -0.72896622, -0.86831735, -0.79357262, -0.65279976,
0.39921356, 0.78018094, 0.75703279, 0.70898895, 1.10155383, 0.88428135, 0.81338108,
0.65611568, 0.89776945, 0.65447442, 0.16289673, 0.19464041, 0.01762445, -0.57663945,
-1.01231868, -0.81204022, -0.99165533, -0.62666993, -1.05661282, -0.78221866, -0.03129549, 1.04051915)
s = -1.59688
i = -0.6373684
z = 0
library(tidyverse)
q %>% as.data.frame() %>% setNames('q') %>%
mutate(q1 = case_when(q >= z ~ 1,
q >= i ~ 2,
q >= s ~ 3,
TRUE ~ 4),
c1 = q1 %in% c(2,3),
c2 = case_when(q1 == 4 ~ F,
q1 == 1 ~ T,
TRUE ~ NA),
c2 = ifelse(row_number() == 1 & is.na(c2), c1, c2),
c3 = case_when(q1 %in% c(1,4) ~ F,
q1 == 3 ~ T,
TRUE ~ NA),
c3 = ifelse(row_number() ==1 & is.na(c3), F, c3)) %>%
fill(c2, c3) %>%
transmute(output = c1 & c2 & c3) %>% pull(output)
#> [1] FALSE TRUE TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE
#> [13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
#> [25] FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE
由reprex package (v2.0.0) 于 2021-06-02 创建
老答案
#data given
q = c(0.00000000, -0.70218526, -0.60635393, 0.32325554, -0.45921704, -0.57336113, -0.77683717,
-1.76347868, -1.90884891, -0.86157465, -0.72896622, -0.86831735, -0.79357262, -0.65279976,
0.39921356, 0.78018094, 0.75703279, 0.70898895, 1.10155383, 0.88428135, 0.81338108,
0.65611568, 0.89776945, 0.65447442, 0.16289673, 0.19464041, 0.01762445, -0.57663945,
-1.01231868, -0.81204022, -0.99165533, -0.62666993, -1.05661282, -0.78221866, -0.03129549, 1.04051915)
s = -1.59688
i = -0.6373684
z = 0
#loading libraries
library(dplyr)
library(tidyr)
#creating zones
q1 <- dplyr::case_when(q >= z ~ 1,
q >= i ~ 2,
q >= s ~ 3,
TRUE ~ 4)
#first condition
c1 <- dplyr::case_when(q1 %in% c(2,3) ~ T,
TRUE ~ F)
#second condition (third in above statements)
c2 <- dplyr::case_when(q1 == 4 ~ F,
q1 == 1 ~ T,
TRUE ~ NA)
c2[1] <- ifelse(is.na(c2[1]), c1[1], c2[1])
c2 <- tidyr::fill(data.frame(id = 1:length(q), c2 = c2), c2)$c2
#third condition
c3 <- dplyr::case_when(q1 == 3 ~ T,
q1 %in% c(1,4) ~ F,
TRUE ~ NA)
c3[1] <- ifelse(is.na(c3[1]), F, c3[1])
c3 <- tidyr::fill(data.frame(id = 1:length(q), c3 = c3), c3)$c3
#creating output
output <- (c1 & c2 & c3)
> output
[1] FALSE TRUE TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[21] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE
#check it with your given `out`
> which((c1 & c2 & c3) == out)
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
#OR
> which((c1 & c2 & c3) != out)
integer(0)
更新如果您只想使用 baseR,请将这些表达式/代码用于 c2 和 c3
#second condition
c2 <- case_when(q1 == 4 ~ F,
q1 == 1 ~ T,
TRUE ~ NA)
c2 <- c2[!cumsum(!is.na(c2)) | !is.na(c2)][cumsum(!cumsum(!is.na(c2)) | !is.na(c2))]
#third condition
c3 <- case_when(q1 == 3 ~ T,
q1 %in% c(1,4) ~ F,
TRUE ~ NA)
c3 <- c3[!cumsum(!is.na(c3)) | !is.na(c3)][cumsum(!cumsum(!is.na(c3)) | !is.na(c3))]
新数据
q <- c(-0.01563733, -0.05829460, -0.05884189, -0.08954093, -0.13268677, -0.31748724, -0.40060792, -0.08515156, -0.14303489, -0.24525535, -0.93842637, -0.77738228, -1.29502715, -0.89000932, -1.49038656, -1.64953167, -1.67114179, -1.47482366, -0.85874778, -1.01021450, -0.90078260, -1.24313333, -0.99053914, -1.11684140, -1.34073045, -1.36406163, -1.25163185, -1.42429376, -1.48127185, -1.79040671, -2.26811789, -1.82124304, -1.85208201, -1.76394637, -1.63173292)
i = -0.489
s = -1.032
z = 0
#after running the above code
> output
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE FALSE FALSE FALSE FALSE
[17] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[33] FALSE FALSE FALSE
和图表
对于具有随机值的新向量
set.seed(202)
q <- runif(35, -2, 2)