#r
#r
Вопрос:
У меня есть пример кода, который witch находит в векторных z
значениях меньше -1.8
и заполняет, 1
пока значения z
не становятся больше, чем 0
при заполнении else 0
.
Я использую два цикла, но это очень медленно.
Как я могу сделать это проще и эффективнее?
z <- c(-1,-1.4,-1.1,-1.8,-2.2,-2.5,-1.7,-1,-0.5,-0.1,0.2,0.4)
q <- NULL
for (i in 1:length(z)) {
if (z[i] <= -1.8) {
temp <- 1
}else temp <- 0
q <- rbind(q, temp)
}
for (i in 2:length(q)) {
if (z[i] < 0 amp; q[i-1] == 1) {
q[i] <- 1
}
}
q
[,1]
temp 0
temp 0
temp 0
temp 1
temp 1
temp 1
temp 1
temp 1
temp 1
temp 1
temp 0
temp 0
Ответ №1:
Вы можете избежать циклов и сделать это в одной строке, если вы это сделаете:
cumsum(c(0, diff( (z <= -1.8)) == 1) - c(0, diff( (z > 0) == 1)))
#> [1] 0 0 0 1 1 1 1 1 1 1 0 0
Это работает путем нахождения, где z
меньше или равно -1.8, и преобразования результирующего логического вектора в 1 или 0. Затем он находит, где это значение изменяется с 0 на 1, используя diff
. Аналогично, он находит, где значения пересекаются выше 0, и отмечает это значением -1. Наконец, он получает совокупную сумму этого вектора.
Если вам нужно более полное решение, одним из вариантов tidyverse будет:
library(dplyr)
library(tidyr)
z <- c(-1, -1.4, -1.1, -1.8, -2.2, -2.5, -1.7, -1, -0.5, -0.1,
0.2, 0.4, -0.5, -1.2, -2, -0.6, -0.1, 0.5)
tibble(z) %>%
mutate(z = (z <= -1.8) - (z > 0),
z = (1 replace(z, z == 0, NA))/2) %>%
fill(z) %>%
replace_na(list(z = 0))
#> # A tibble: 18 x 1
#> z
#> <dbl>
#> 1 0
#> 2 0
#> 3 0
#> 4 1
#> 5 1
#> 6 1
#> 7 1
#> 8 1
#> 9 1
#> 10 1
#> 11 0
#> 12 0
#> 13 0
#> 14 0
#> 15 1
#> 16 1
#> 17 1
#> 18 0
Создан 2020-09-26 пакетом reprex (версия 0.3.0)
Комментарии:
1. стоит отметить, что после того, как я заполнил 1, я должен снова подождать, пока значения не станут меньше -1,8, и снова начать заполнять 1 только с того момента, когда z станет равным -1,8 более сложный пример: z <- c(-1,-1.4,-1.1,-1.8,-2.2,-2.5,-1.7,-1,-0.5,-0.1,0.2,0.4,-0.5,-1.2,-2,-0.6,-0.1,0.5) что должно произойти: 0 0 0 1 1 1 1 1 1 1 0 0 0 0 1 1 1 0
2. @МихаилТабаков see my update. Надеюсь, это будет быстрее