基于R中V2中设置的条件,列V1中的值之和
我希望根据以下条件创建列中多个值的总和: 假设我有以下数据基于R中V2中设置的条件,列V1中的值之和,r,loops,if-statement,sum,R,Loops,If Statement,Sum,我希望根据以下条件创建列中多个值的总和: 假设我有以下数据 Z <- matrix(c(1,2,3,4,5,6,7,8,9,10,0,0,1,1,0,0,0,0,0,1), nrow = 10, ncol = 2) 现在我只想求V2中的第一个1和V2中的第一个值之间的值的和,然后是四个零。在本例中,这将是[3,1]和[4,1]之和,因为[3,2]包含第一个零,[4,2]是第一个值,后面分别是四个零。[5,2]、[6,2]、[7,2]和[8,2] 我试着跟随循环和它的变化,但它不断给出错误
Z <- matrix(c(1,2,3,4,5,6,7,8,9,10,0,0,1,1,0,0,0,0,0,1), nrow = 10, ncol = 2)
现在我只想求V2中的第一个1和V2中的第一个值之间的值的和,然后是四个零。在本例中,这将是[3,1]和[4,1]之和,因为[3,2]包含第一个零,[4,2]是第一个值,后面分别是四个零。[5,2]、[6,2]、[7,2]和[8,2]
我试着跟随循环和它的变化,但它不断给出错误
for(j in 1:10){
ifelse(V2(j) == 1,
(for i in (j:(10-j+1)){
ifelse (V2(i+1) == 0 & V2(i+2) == 0 & V2(i+3) == 0 & V2(i+4) == 0, total <- sum(V1(c(j:i))), next)})
, next)
}
我们可以尝试从data.table转换
使用基本R rle/reverse.rle函数的可能解决方案
res <- inverse.rle(within.list(rle(Z[, 2] == 0), values[lengths < 4] <- 0))
sum(Z[which.max(Z[, 2]) : (which.max(res) - 1), 1])
# [1] 7
使用简单for循环:
Z <- matrix(c(1,2,3,4,5,6,7,8,9,10,0,0,1,1,0,0,0,0,0,1), nrow = 10, ncol = 2)
index1 <- which(Z[,2]==1)
sum <- 0
if (length(index1) > 0) {
index1 <- index1[1]
index2 <- NULL
indices <- index1-1+which(Z[index1:nrow(Z),2]==0)
for (i in 1:(length(indices)-3)) {
if (all((indices[i]+(0:3))==indices[i:(i+3)])) {
index2 <- (indices[i] - 1) # position of first consecutive 0s after the first 1 is indices[i]
break
}
}
sum <- ifelse(!is.null(index2), sum(Z[index1:index2, 1]), 0)
}
sum
[1] 7
使用zoo包中的rollapply的另一个可能的解决方案是
library(zoo)
ind <- c(which(Z[,2] == 1)[1], which(rollapply(Z[,2], 4, by = 1, sum) == 0)[1] - 1)
sum(Z[ind,1])
#[1] 7
这很有效。有没有一种方法可以包含一个选项,用于当1没有第一个1时,V2中的所有值都是0,而2没有4个零的序列?在第一种情况下,总和应为0,在后一种情况下,总和应为固定金额,例如在前1和10个期间之间。对不起,还有其他问题。那么输出应该是零。第二种情况下的固定金额是多少?您能为两种情况下的x值做固定和吗?例如8,当V2中的所有内容都为0时,从一开始,或者当V2中没有4个零的序列时,从第一个1开始。
Z <- matrix(c(1,2,3,4,5,6,7,8,9,10,0,0,1,1,0,0,0,0,0,1), nrow = 10, ncol = 2)
index1 <- which(Z[,2]==1)
sum <- 0
if (length(index1) > 0) {
index1 <- index1[1]
index2 <- NULL
indices <- index1-1+which(Z[index1:nrow(Z),2]==0)
for (i in 1:(length(indices)-3)) {
if (all((indices[i]+(0:3))==indices[i:(i+3)])) {
index2 <- (indices[i] - 1) # position of first consecutive 0s after the first 1 is indices[i]
break
}
}
sum <- ifelse(!is.null(index2), sum(Z[index1:index2, 1]), 0)
}
sum
[1] 7
library(zoo)
ind <- c(which(Z[,2] == 1)[1], which(rollapply(Z[,2], 4, by = 1, sum) == 0)[1] - 1)
sum(Z[ind,1])
#[1] 7