Как определить, сколько раз условие истинно, пока оно в среднем не верно в r? - PullRequest
0 голосов
/ 10 мая 2019

Я пытаюсь прочесать фондовые данные, и я обычно использую Java, но недостаточно хорошо для того, что я в конечном итоге выстрою.В R, как я могу проверить, сколько раз условие истинно, пока оно в среднем не будет ложным, поэтому, если X> 10 = true, если x <10 = false </p>

, сколько раз x> 10, пока оно не станет ниже

Ответы [ 2 ]

1 голос
/ 10 мая 2019

Я только недавно начал использовать R и (если я правильно понял ваш вопрос) я столкнулся с подобными проблемами.

Сначала я генерирую выборку из 1000 элементов со случайными значениями от 0 до 20 (я выбрал 20 просто потому, что ваше состояние было бы <> 10, поэтому я взял 10 в качестве средней точки)

library(dplyr)
x <- data.frame(n=runif(1000, min = 0, max = 20), group = 0)
> x
#               n group
#1    18.01267749     0
#2     8.50561210     0
#3    11.26424876     0
#4     1.22902009     0
#5    17.37173610     0
#6    15.79453081     0
#7     4.84231228     0
#8     1.36992180     0
#9     2.16605579     0
#10   16.51773243     0
...

Я не уверен, что вы конкретно имеете в виду, но постараюсь решить две проблемы: 1- Подсчитайте, сколько строк соответствует определенному условию, а сколько - нет. 2- Проверьте, сколько последовательных «строк» ​​соответствует определенному условию, пока условие больше не будет выполнено.

Теперь для первого случая, думая «программированием» с помощью for-loop:

res2 <- c(0,0)
for(i in 1:nrow(x)){
  if(x[[i,"n"]] > 10)
    res2[1] <- res2[1]+1
  else
    res2[2] <- res2[2]+1
}
#> res2
#[1] 494 506

Конечно, есть лучший и более быстрый способ сделать это, способ "R":

res <- x %>%
    group_by(group = if_else(x$n > 10, 1, 0)) %>%
    summarise(total = n())
# A tibble: 2 x 2
#  group total
#  <dbl> <int>
#1     0   506
#2     1   494

Идея проста: поместить все строки со значением> 10 в группу (обозначенную 1, а строки с n <10 в другую группу, обозначенную 0), затем сгруппировать с переменной <code>group и наконец подсчитайте общее количество строк в двух группах.

Теперь для второго случая, который немного сложнее, если у вас нет нужных инструментов. Тогда мне потребовалось некоторое время, чтобы найти правильный ответ без использования циклов for.

Идея состоит в том, чтобы использовать rle или кодировку по длине прогона:

x$group <- with(rle(x$n < 10), rep(seq_along(lengths), lengths))
#> x
#               n group
#1    18.01267749     1
#2     8.50561210     2
#3    11.26424876     3
#4     1.22902009     4
#5    17.37173610     5
#6    15.79453081     5
#7     4.84231228     6
#8     1.36992180     6
#9     2.16605579     6
#10   16.51773243     7
#11    2.22784827     8
#12   19.44676961     9
#13    1.28190206    10
#14   15.93426880    11
#15   16.70963107    11
#16    5.01572254    12

То, что rle делает, - это генерирует новый групповой индекс всякий раз, когда происходит изменение в результате условия. Поэтому если в строке 3 значения, все из которых <10, все они будут иметь один и тот же групповой индекс, но как только значение больше не будет соответствовать условию, индекс группы будет увеличиваться. </p>

В этом примере вы можете заметить, что строки 5-6 имеют значение> 10, а их группа имеет индекс 5, но строка 7 имеет значение <10, поэтому индекс новой группы равен <code>6 и так далее ...

Теперь, поскольку групповой индекс меняется каждый раз, когда изменяется результат условия, чтобы узнать, сколько раз он меняется, вы можете просто получить самый большой групповой индекс и разделить на два.

> max(x$group)/2
# [1] 242

Вы можете проверить это, выполнив:

runLength <- rle(x$n < 10)$values
res <- length(runLength[runLength == TRUE])
#> res
#[1] 242
0 голосов
/ 10 мая 2019

Я произвел данные, используя runif, как @ Gabryxx7, но это решение однострочное (я думаю, это то, что вы искали в любом случае).

# Data
set.seed(123)
x <- data.frame(n=runif(1000, min = 0, max = 20))

# Solution
mean(rle(x$n > 10)$lengths[rle(x$n > 10)$values == T])
[1] 2.020492

Я объясню, что происходитна.Часть x$n > 10 выводит TRUE, если значения в столбце n в объекте x больше 10. Это действительно так просто.

Здесь все пошагово.

# Create column in x for whether value is greater than 10
x$GreaterThanTen <- x$n > 10

# Input rle output into object
ConsecutiveVars <- rle(x$GreaterThanTen)

ConsecutiveVars$lengths # (1 1 1 2 1) Tells us some value occurs consecutively: once, once, once, twice, once, etc.
ConsecutiveVars$values # (F T F T F) Tells us which values occur consecutively: FALSE then TRUE then FALSE then TRUE then FALSE, etc.

# so FALSE occurs once, then TRUE occurs once, then FALSE occurs once, then TRUE occurs twice, then FALSE occurs once, etc.

# We want to know only how many times TRUE occurs consecutively, so we filter ConsecutiveVars$lengths for when it is TRUE
ConsecutiveTRUES <- ConsecutiveVars$lengths[ConsecutiveVars$values == T]

# Then take the average
mean(ConsecutiveTRUES)
2.020492
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...