首页 > 解决方案 > 向量根据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

我需要创建一个新向量,其中将根据以下条件填充布尔值:

结果,对于这个示例数据,您应该得到以下结果(我手动填写):

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 中太慢了

标签: 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,它只有在到达/命中时才能变为 TRUE zone 1,至少一次。

战略

  • 为了整合这些,我使用了 tidyverse 管道语法
    1. 首先划分各个区域中的所有值(例如q1
    1. 作为第一个条件TRUE,在 `FALSE 中划分区域 2 和 3 以及其他区域
    1. 作为第二个条件,例如c2,即是否从区域 4 退出并到达区域 1,将区域 4 标记为F,将区域 1 标记为T静止,全部为 NA。
    • 第一个值可以NA这样替换第一个值,如果 NA,用 c1
    1. 作为最后一个条件c3,即当到达区域 3 时为 TRUE,将 3 标记为TRUE1,将 4 标记为FALSE并离开区域 2,NA以便稍后检查它是否从哪个区域到达这里。
    • 第一个值可以NA这样替换第一个值,如果 NA,用FALSE
    • 现在剩下的工作就是填写 NAc2c3. 使用zoo::na.locftidyr::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,请将这些表达式/代码用于c2c3


#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)

在此处输入图像描述


推荐阅读