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