如何计算条件满足多少次直到在r中平均不满足?

时间:2019-05-10 04:09:46

标签: r

我正在尝试通过股票数据进行梳理,我通常使用Java,但对于我最终将要建立的东西还不够好。在R中,我如何检查条件为真直到平均为假的次数 所以如果X> 10 = true    如果x <10 =假

x> 10直到其下多少次

2 个答案:

答案 0 :(得分:1)

我最近才开始使用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-检查有多少连续的“行”满足某个条件,直到不再满足该条件。

现在,对于第一种情况,使用“循环”以“编程”方式进行思考:

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标识的组中),然后将变量{{ 1}},最后计算两组的总行数。

现在是第二种情况,如果没有正确的工具,则稍微困难。实际上,我花了一段时间才找到正确的答案,而无需使用for循环。

想法是使用rle或游程长度编码:

group

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 的作用是在条件结果发生变化时生成新的组索引。因此,如果一行中有3个均小于10的值,它们将具有相同的组索引,但是一旦某个值不再满足条件,组索引就会增加。

在示例中您会注意到,第5-6行均大于10,并且它们的组具有索引rle,但第7行是<10,因此新的组索引为5,依此类推上...

现在,由于组索引每次条件结果更改时都会更改,因此为了知道它更改了多少次,您只需获取最大的组索引并除以二即可。

6

您可以通过以下方法进行测试:

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

答案 1 :(得分:0)

我像@ Gabryxx7一样使用runif生成了数据,但是这种解决方案是单线的(无论如何,我认为这是您一直在寻找的东西)。

# 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,则x$n > 10部分将输出TRUE。就这么简单。

这是逐步的。

# 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