对于许多位置(这么多行)我有一个data.frame
变量的月值,我想计算值为零的连续月数(即连续单元格) 。如果只是从左到右阅读,这将很容易,但增加的复杂性是,年底是连续到年初。
例如,在下面缩短的示例数据集中(有季节而不是几个月),位置1有3' 0' 0月份,位置2有2个,3个没有。
df<-cbind(location= c(1,2,3),
Winter=c(0,0,3),
Spring=c(0,2,4),
Summer=c(0,2,7),
Autumn=c(3,0,4))
如何计算这些连续的零值?我看过rle
,但我目前还不是更聪明的人!
非常感谢任何帮助:)
答案 0 :(得分:2)
您已经确定了最长跑可以采取的两种情况:(1)中间某处或(2)在每一行的结束和开始之间分开。因此,您想要计算每个条件并采用最大值:
df<-cbind(
Winter=c(0,0,3),
Spring=c(0,2,4),
Summer=c(0,2,7),
Autumn=c(3,0,4))
#> Winter Spring Summer Autumn
#> [1,] 0 0 0 3
#> [2,] 0 2 2 0
#> [3,] 3 4 7 4
# calculate the number of consecutive zeros at the start and end
startZeros <- apply(df,1,function(x)which.min(x==0)-1)
#> [1] 3 1 0
endZeros <- apply(df,1,function(x)which.min(rev(x==0))-1)
#> [1] 0 1 0
# calculate the longest run of zeros
longestRun <- apply(df,1,function(x){
y = rle(x);
max(y$lengths[y$values==0],0)}))
#> [1] 3 1 0
# take the max of the two values
pmax(longestRun,startZeros +endZeros )
#> [1] 3 2 0
当然更简单的解决方案是:
longestRun <- apply(cbind(df,df),# tricky way to wrap the zeros from the start to the end
1,# the margin over which to apply the summary function
function(x){# the summary function
y = rle(x);
max(y$lengths[y$values==0],
0)#include zero incase there are no zeros in y$values
})
请注意,上述解决方案有效,因为我的df
不包含location
字段(列)。
答案 1 :(得分:2)
试试这个:
df <- data.frame(location = c(1, 2, 3),
Winter = c(0, 0, 3),
Spring = c(0, 2, 4),
Summer = c(0, 2, 7),
Autumn = c(3, 0, 4))
maxcumzero <- function(x) {
l <- x == 0
max(cumsum(l) - cummax(cumsum(l) * !l))
}
df$N.Consec <- apply(cbind(df[, -1], df[, -1]), 1, maxcumzero)
df
# location Winter Spring Summer Autumn N.Consec
# 1 1 0 0 0 3 3
# 2 2 0 2 2 0 2
# 3 3 3 4 7 4 0
这会在数据帧中添加一列,指定在数据帧的每一行中连续出现零的最大次数。数据框是自身的列绑定,以便能够检测秋冬之间的连续零。
此处使用的方法基于Martin Morgan的answer to this similar question。