我有一个带有值的列,想要检查5个连续值的总和(在某个范围内 - 第259行到第272行)是否> 10,并且如果5个值中的至少两个> 3
这是我过去常常得出5个连续值的总和。它将我的范围分成12个区块并单独检查每个区块。
data <- read.table("....csv", header=TRUE, sep=",", na.strings="NA", dec=".", strip.white=TRUE)
interval <- 5
start <- 259
end <- 272
block<-sapply(start:(end-interval+1),function(x){sum(data[x:(x+interval-1)])})
现在我检查块的值是否为&gt; 10
if ( block [[1]]> 10 ) {
print(paste("block to fulfill the condition is block", 1))
} else if ( block [[2]]> 10 ) {
print(paste("block to fulfill the condition is block", 2))
....
如何在if-clause中包含条件“块中的5个值中的两个必须> 3”?
答案 0 :(得分:2)
为了使其成为可重现的示例,我在mtcars
数据集上尝试了它。
第259行至第272行仅针对总和大于20的gear
列更改为20至30,并且至少有5个值中的2个值大于3。
library(zoo)
subvec = mtcars[20:30, "gear"]
subvec
#[1] 4 3 3 3 3 3 4 5 5 5 5
idx <- which(rollsum(subvec, 5) > 20 & rollapply(subvec, 5,
function(x) sum(x > 3)) >= 2)[1]
idx
# [1] 6
subvec[idx:(idx+4)]
#[1] 3 4 5 5 5
所以我认为这应该适用于您的数据集,
library(zoo)
subvec = data[259:272, "column"]
idx <- which(rollsum(subvec, 5) > 10 & rollapply(subvec,5,
function(x) sum(x > 3)) >= 2)[1]
subvec[idx:(idx+4)]
正如@ G.Grothendieck所提到的,我们可以进一步简化代码。我们可以在布尔向量上使用rollapply
,然后对rollsum
之类的
TRUE
。
idx <- which(rollsum(subvec, 5) > 10 & rollsum(subvec > 3, 5) >= 2)[1]
答案 1 :(得分:1)
有数据:
set.seed(1453)
x = sample(-3:7, 13, TRUE)
n = 5
x
# [1] 4 1 6 -1 2 3 5 0 1 4 1 5 5
一种方法是:
ex = embed(x, n)
(rowSums(ex) > 10) & (rowSums(ex > 3) >= 2)
#[1] TRUE FALSE TRUE FALSE FALSE TRUE TRUE TRUE TRUE
为避免重新计算相同的添加项,我们可以使用cumsum
:
cs1 = cumsum(x)
cond1 = cs1[n:length(x)] - c(0, cs1[1:(length(x) - n)]) > 10
cs2 = cumsum(x > 3)
cond2 = cs2[n:length(x)] - c(0, cs2[1:(length(x) - n)]) >= 2
cond1 & cond2
#[1] TRUE FALSE TRUE FALSE FALSE TRUE TRUE TRUE TRUE
答案 2 :(得分:0)
所以我不太确定这是不是你想要的。但是这里有一个检查两个条件的函数,给定start_row
,end_row
和finder = function(column,start_row,end_row,threshold_1 = 10){
for(i in start_row:end_row){
if(sum(column[i:(i+4)])> threshold_1){
if(sum(column[i:(i+4)]>3)>=2){
print(paste("sum of row",i,"and its 4 consecutive values is greater than", threshold_1))
print("And at least two out of the 5 values are greater than 3")
return("END")
}}}}
,
set.seed(123)
col = sample(1:5, 300, T)
finder(col,259,279)
[1] "sum of row 269 and its 4 consecutive values is greater than 10"
[1] "And at least two out of the 5 values are greater than 3"
[1] "END"
这非常混乱,但主要是由于打印消息。 这就是你得到的:
{{1}}
答案 3 :(得分:0)
您可以使用rollapply
包中的zoo
和intersect
,如下所示,
library(zoo)
ind1 <- which(rollapply(data$v1, 5, by = 1, sum) > 10)
ind2 <- which(rollapply(x, 5, by = 1, function(i)length(i[i>3]) >= 2))
intersect(ind1, ind2)