0

我有一个数据集,它是多个数据记录器的输出,每隔 1 小时测量一次温度和勒克斯(光强度)。
大约有。250,000 个数据点。我遇到了来自“太阳斑点”的温度读数问题,其中一束光照射到记录器上,快速加热它,然后在一天的剩余时间里给出“温暖”的读数。我可以使用 dplyr 对这些数据进行子集化(即 LUX>32,000),但如果记录仪的 LUX>32,000 读数,我想删除当天的所有读数。对于 ref,每个数据记录器都有一个名称、日期和时间变量。

有没有办法用 dplyr 做到这一点?

4

2 回答 2

1

如果我没记错的话,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)
于 2018-05-16T18:20:58.780 回答
0

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.

于 2018-05-16T18:27:38.970 回答