我试图从之前创建的结果集中获取特定计数。我需要在包含NA' s的行之间计算行数。这些行的值的聚合不重要,只有计数。
下面是一个非常简单的例子,希望能更好地解释我在说什么。左边是实际数据,右边是所需结果。
+------+-------+---+------+--------+ | TIME | Value | - | TIME | Result | +------+-------+---+------+--------+ | 10 | NA | - | 20 | 2 | | 20 | 0 | - | 60 | 3 | | 30 | 1 | - | | | | 40 | NA | - | | | | 50 | NA | - | | | | 60 | 30 | - | | | | 70 | 68 | - | | | | 80 | 0 | - | | | | 90 | NA | - | | | +------+-------+---+------+--------+
欢迎任何评论。如果需要额外输入,请留言。
答案 0 :(得分:6)
为了使我的答案在这里完成修改版本:
d <- data.frame( TIME = seq(10, 90, by = 10), Value = c(NA, 0, 1, NA, NA, 30, 68, 0, NA))
aux <- rle(as.numeric((!is.na(d[,2]))))
cbind(TIME = d[cumsum(aux$lengths)[which(aux$values == 1)] - aux$lengths[aux$values == 1] +1, 1],
Result = rle(is.na(d$Value))$lengths[!rle(is.na(d$Value))$values])
TIME Result
[1,] 2 20
[2,] 3 60
答案 1 :(得分:6)
除rle
外,您还可以使用diff
,which
和is.na
的组合:
dat <- data.frame(time = seq(10, 90, 10), value = c(NA, 0, 1, NA, NA, 30, 68, 0, NA))
res <- data.frame(result = diff(which(is.na(dat$value))) - 1)
res$time <- dat$time[which(is.na(dat$value)) + 1][1:nrow(res)]
res[res$result != 0, ]
# time result
# 20 2
# 60 3
答案 2 :(得分:5)
我的"SOfun" package有a function called TrueSeq
,就像一个带有逻辑向量的群组制作者。您可以将该函数与“data.table”结合使用以获得所需的结果,如下所示:
library(SOfun)
library(data.table)
na.omit(data.table(TIME = df$TIME, Val = TrueSeq(
!is.na(df$value), zero2NA = TRUE)))[, list(TIME = TIME[1], .N), by = Val]
# Val TIME N
# 1: 1 20 2
# 2: 2 60 3
如果您安装了“devtools”,则可以使用以下命令安装“SOfun”
library(devtools)
install_github("mrdwab/SOfun")
作为参考,I've posted this Gist能够在此答案中比较不同方法的结果。
总结:
NA
:
NA
:
NA
值开始(因此,输入的第一行)作为结果的第一行。 NA
值开始,作为结果的第一行。答案 3 :(得分:3)
这可能不是最直接的方法,但它确实产生了预期的结果,因为我写了它,我想我也可以发布它(使用@konvas的样本数据):
require(dplyr)
dat %>%
group_by(m = cumsum(is.na(value))) %>%
summarise(n = n() -1, time = first(time[!is.na(value)])) %>%
ungroup() %>%
filter(n > 0 & m > 0) %>%
select(-m)
#Source: local data frame [2 x 2]
#
# n time
#1 2 20
#2 3 60
编辑:为了回应Ananda的评论,我做了一个小小的修正,希望它现在更好用。
例如,如果数据是:
dat <- data.frame(time = seq(10, 90, 10), value = c(0, 2, 1, NA, NA, 30, 68, 0, NA))
dat
# time value
#1 10 0
#2 20 2
#3 30 1
#4 40 NA
#5 50 NA
#6 60 30
#7 70 68
#8 80 0
#9 90 NA
代码会导致:
dat %>%
group_by(m = cumsum(is.na(value))) %>%
summarise(n = n() -1, time = first(time[!is.na(value)])) %>%
ungroup() %>%
filter(n > 0 & m > 0) %>%
select(-m)
#Source: local data frame [1 x 2]
#
# n time
#1 3 60