首页 > 解决方案 > 根据另一列的最大实例数对数据框进行子集

问题描述

我有一些以下格式的数据,其中多个传感器的数据带有时间戳。每个传感器之间的时间戳有一些重叠,但是在一些传感器中存在根本不存在数据的间隙。我希望以一种仅提取每个传感器都有记录的时间戳/行的方式对数据进行子集化。这是一个小例子:

library(lubridate)
set.seed(88)

start_date = as.POSIXct("2018-08-13 17:30:00 GMT")
datetime = seq(start_date, start_date + minutes(20), by = "5 min")

df <- data.frame(Datetime = datetime, X = runif(15), Sensor = 
c(rep(1,5),rep(2,3),rep(3,4),rep(4,3)))
df$Datetime[12] <- df$Datetime[12] + minutes(5)
df

              Datetime          X Sensor
1  2018-08-13 17:30:00 0.71008793      1
2  2018-08-13 17:35:00 0.23754185      1
3  2018-08-13 17:40:00 0.43144271      1
4  2018-08-13 17:45:00 0.06922129      1
5  2018-08-13 17:50:00 0.78754994      1
6  2018-08-13 17:30:00 0.74219767      2
7  2018-08-13 17:35:00 0.49680693      2
8  2018-08-13 17:40:00 0.28491360      2
9  2018-08-13 17:45:00 0.62937634      3
10 2018-08-13 17:50:00 0.28642922      3
11 2018-08-13 17:30:00 0.44928292      3
12 2018-08-13 17:40:00 0.97428628      3
13 2018-08-13 17:40:00 0.10112843      4
14 2018-08-13 17:45:00 0.89788230      4
15 2018-08-13 17:50:00 0.53922885      4

这里所需的输出是:

                  Datetime         X Sensor
3  2018-08-13 17:40:00 0.4314427      1
8  2018-08-13 17:40:00 0.2849136      2
12 2018-08-13 17:40:00 0.9742863      3
13 2018-08-13 17:40:00 0.1011284      4

标签: rdataframedplyr

解决方案


我们可以dplyr通过只保留条目等于传感器数量的日期来做到这一点;

df %>% group_by(Datetime) %>%  filter(n()==n_distinct(.$Sensor))

#> # A tibble: 4 x 3
#> # Groups:   Datetime [1]
#>   Datetime                X Sensor
#>   <dttm>              <dbl>  <dbl>
#> 1 2018-08-13 17:40:00 0.741      1
#> 2 2018-08-13 17:40:00 0.760      2
#> 3 2018-08-13 17:40:00 0.744      3
#> 4 2018-08-13 17:40:00 0.553      4


另一种方法base是将数据从 long 转换为 wide 并仅保留已完成的案例(具有全部数据的案例Sensors),然后将结果转换回长格式;

wide <- reshape(df, idvar = "Datetime", timevar = "Sensor", direction = "wide")

reshape(na.omit(wide), direction = "long", varying = list(names(wide)[-1]), v.names = "X", 
        idvar = "Datetime", timevar = "Sensor", times = unique(df$Sensor)); rm(wide)
#>                                  Datetime Sensor          X
#> 2018-08-13 17:40:00.1 2018-08-13 17:40:00      1  0.7410448
#> 2018-08-13 17:40:00.2 2018-08-13 17:40:00      2  0.7602078
#> 2018-08-13 17:40:00.3 2018-08-13 17:40:00      3  0.7441643
#> 2018-08-13 17:40:00.4 2018-08-13 17:40:00      4  0.5529621

reprex 包(v0.3.0)于 2019-05-31 创建


推荐阅读