我有一个数据集,它是多个数据记录器的输出,每隔 1 小时测量一次温度和勒克斯(光强度)。
大约有。250,000 个数据点。我遇到了来自“太阳斑点”的温度读数问题,其中一束光照射到记录器上,快速加热它,然后在一天的剩余时间里给出“温暖”的读数。我可以使用 dplyr 对这些数据进行子集化(即 LUX>32,000),但如果记录仪的 LUX>32,000 读数,我想删除当天的所有读数。对于 ref,每个数据记录器都有一个名称、日期和时间变量。
有没有办法用 dplyr 做到这一点?
我有一个数据集,它是多个数据记录器的输出,每隔 1 小时测量一次温度和勒克斯(光强度)。
大约有。250,000 个数据点。我遇到了来自“太阳斑点”的温度读数问题,其中一束光照射到记录器上,快速加热它,然后在一天的剩余时间里给出“温暖”的读数。我可以使用 dplyr 对这些数据进行子集化(即 LUX>32,000),但如果记录仪的 LUX>32,000 读数,我想删除当天的所有读数。对于 ref,每个数据记录器都有一个名称、日期和时间变量。
有没有办法用 dplyr 做到这一点?
如果我没记错的话,filter
它不适用于分组数据,所以我首先按时间对数据框进行排序(如果您的数据已经正确排序,这可能没有必要)。然后,对于每个记录器和日期,我在LUX > 32000
事件后识别所有点并标记它们。完成后,过滤器应该可以工作了。
df %>%
arrange(name, date, time) %>%
group_by(name, date) %>%
mutate(
fleck = cumsum(LUX > 32000) > 0
) %>%
ungroup() %>%
filter(!fleck)
如果要删除一整天,可以更改fleck
变量的定义方式。例如,
fleck = any(LUX > 32000)
You can use a somewhat simple function like this:
beforeafter <- function(lgl, before=1L, after=1L, default=FALSE) {
befores <- if (before > 0L) sapply(seq_len(before), function(i) c(tail(lgl, n=-i), rep(default, i))) else c()
afters <- if (after > 0L) sapply(seq_len(after), function(i) c(rep(default, i), head(lgl, n=-i))) else c()
apply(cbind(befores, lgl, afters), 1, any)
}
vec <- (1:10 == 5)
vec
# [1] FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE
beforeafter(vec)
# [1] FALSE FALSE FALSE TRUE TRUE TRUE FALSE FALSE FALSE FALSE
beforeafter(vec, before=2, after=0)
# [1] FALSE FALSE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE
As an example:
rownames_to_column(mtcars) %>%
select(rowname, cyl, gear) %>%
filter(cyl == 4L, gear == 3L)
# rowname cyl gear
# 1 Toyota Corona 4 3
rownames_to_column(mtcars) %>%
select(rowname, cyl, gear) %>%
filter(beforeafter(cyl == 4L & gear == 3L))
# rowname cyl gear
# 1 Toyota Corolla 4 4
# 2 Toyota Corona 4 3
# 3 Dodge Challenger 8 3
This works well if your data is a constant frequency and you want to remove all observations within some constant samples from a known problem. It does not work as well when you want "within some time" from variable-frequency data. For that, I think you'll need dist
iteratively on all "known bad" points.