r - 向量根据R中的给定条件填充真或假,没有循环
问题描述
我有样本向量和一些值:
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
我需要创建一个新向量,其中将根据以下条件填充布尔值:
- 如果q小于i我们填充TRUE直到
- q变得大于0(即z)
- 或直到q变得小于s。
- 如果由于s值的条件而停止了填充,则需要等到q变得大于0(即z)并且
- 之后才可以重新开始填写TRUE,否则填写FALSE
结果,对于这个示例数据,您应该得到以下结果(我手动填写):
out <- c(FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE,
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE)
out
[1] FALSE TRUE TRUE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE
我想不使用循环,因为它们在 R 中太慢了
解决方案
** 鉴于 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
,它就会变成TRUE
只有当它到达时zone 3
- 此外,如果它已经 hit
zone 4
,它只有在到达/命中时才能变为 TRUEzone 1
,至少一次。
战略
- 为了整合这些,我使用了 tidyverse 管道语法
-
- 首先划分各个区域中的所有值(例如
q1
)
- 首先划分各个区域中的所有值(例如
-
- 作为第一个条件
TRUE
,在 `FALSE 中划分区域 2 和 3 以及其他区域
- 作为第一个条件
-
- 作为第二个条件,例如
c2
,即是否从区域 4 退出并到达区域 1,将区域 4 标记为F
,将区域 1 标记为T
静止,全部为 NA。
- 第一个值可以
NA
这样替换第一个值,如果 NA,用 c1
- 作为第二个条件,例如
-
- 作为最后一个条件
c3
,即当到达区域 3 时为 TRUE,将 3 标记为TRUE
1,将 4 标记为FALSE
并离开区域 2,NA
以便稍后检查它是否从哪个区域到达这里。
- 第一个值可以
NA
这样替换第一个值,如果 NA,用FALSE
- 现在剩下的工作就是填写 NA
c2
和c3
. 使用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 包创建于 2021-06-02 (v2.0.0 )
旧答案
#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)
推荐阅读
- angular - How to create a mat-tree from firebase data in angular
- python - 如何在 Windows 10 中使用 python3.9 检查文件是否在我的 python 脚本之外的另一个进程中主动打开?
- php - 强制显示购物车
- vmware-workstation - 在 CentOS 8 上安装 GlusterFS 不起作用
- web - IIS 上的某些网站已关闭,无法启动它们。其他运行良好
- javascript - 'TypeError:无法读取未定义的属性'不正确',但console.log显示没有未定义的内容
- powerbi - 未选择筛选值
- python - 将 2D 数组更改为 3D 数组
- python - 从两个 JSON 数组中获取平均值
- javascript - 如何使用范围滑块输入值复制或克隆元素?