我有一个每小时的值。我想计算从上次不为零以来连续多少小时该值为零。这对于电子表格或循环而言很容易,但我希望能够用一行快速的向量化代码来完成任务。
x <- c(1, 0, 1, 0, 0, 0, 1, 1, 0, 0)
df <- data.frame(x, zcount = NA)
df$zcount[1] <- ifelse(df$x[1] == 0, 1, 0)
for(i in 2:nrow(df))
df$zcount[i] <- ifelse(df$x[i] == 0, df$zcount[i - 1] + 1, 0)
期望的输出:
R> df
x zcount
1 1 0
2 0 1
3 1 0
4 0 1
5 0 2
6 0 3
7 1 0
8 1 0
9 0 1
10 0 2
(!x) * unlist(lapply(rle(x)$lengths, seq_len))
(lapply
更安全、更快,seq_len
是seq
的简化版本),大约快了 2 倍。 - Marekseq_len
更快,很好知道;为什么lapply
更安全?此外,rle
并不特别快;我有一种烦人的感觉,可以使用纯算术运算而无需分解数组和重新组装等方式更快地完成这项工作(例如,涉及cumsum
的某些内容)。 - Prasad Chalasanilapply
总是返回列表,而sapply
有时不会,例如尝试使用x <- c(0,0,1,1,0,0,1,1)
进行代码测试。除此之外,在这里使用基于lapply
的函数已经足够了,所以为什么要使用其他函数呢? - Marekvapply
是sapply
的更安全的版本,因为你可以告诉它输出类型应该是什么。 - hadley