删除日期行,并为具有NA的任何日期重复日期

时间:2018-12-01 19:50:05

标签: r dplyr

我希望从具有重复日期的data.frame中删除所有具有任何观测值的NA /缺失数据的日期。例如,在这里我想以只有data.frame数据的三行2018-12-05结尾。我的非示例data.frame很长,因此,如果有几种方法,我倾向于运行时而不是可读性,并且我愿意使用tidyverse和非tidyverse方法。

date_time <- rep(seq(from=as.POSIXct("2018-12-01", tz="GMT"), 
             to=as.POSIXct("2018-12-05", tz="GMT"), by="1 day"),3)
value     <- c(1,2,NA,NA,5,NA,NA,NA,4,5,7,NA,NA,NA,8)
class     <- c(rep("a", 5), rep("b", 5), rep("c", 5))
df        <- data.frame(date_time, value, class)

来自:

enter image description here

过滤到:

enter image description here

2 个答案:

答案 0 :(得分:2)

如果您需要速度,我不知道。但是下面的函数仅保留日期的所有值均为class的行。

fun <- function(DF){
  DF2 <- DF[!is.na(DF$value), ]
  u <- unique(DF2$class)
  sp <- split(DF2, DF2$date_time)
  inx <- sapply(sp, function(d){
    all(u %in% d$class)
  })
  DF2 <- do.call(rbind, sp[inx])
  row.names(DF2) <- NULL
  DF2
}

fun(df)
#   date_time value class
#1 2018-12-05     5     a
#2 2018-12-05     5     b
#3 2018-12-05     8     c

编辑。
这是一个比较速度测试。 Camille's answer在较大的数据帧中速度更快,而速度更重要。而且更好。

library(microbenchmark)
library(ggplot2)
library(dplyr)

fun2 <- function(DF){
  DF %>%
    arrange(date_time, class) %>%
    group_by(date_time) %>%
    mutate(all_vals = all(!is.na(value))) %>%
    filter(all_vals)
}

mb <- microbenchmark(
  rui = fun(df),
  camille = fun2(df)
)
mb1 <- microbenchmark(
  rui = fun(df1),
  camille = fun2(df1)
)

ap <- autoplot(mb)
ap1 <- autoplot(mb1)
cowplot::plot_grid(ap, ap1)

enter image description here

答案 1 :(得分:1)

在某些dplyr函数中,您可以使用基本all。按日期分组,然后查找每个组的所有值是否均为非{NA

还有一些额外的步骤来说明:

library(dplyr)

df %>%
  arrange(date_time, class) %>%
  group_by(date_time) %>%
  mutate(all_vals = all(!is.na(value))) %>%
  filter(all_vals)
#> # A tibble: 3 x 4
#> # Groups:   date_time [1]
#>   date_time           value class all_vals
#>   <dttm>              <dbl> <fct> <lgl>   
#> 1 2018-12-05 00:00:00     5 a     TRUE    
#> 2 2018-12-05 00:00:00     5 b     TRUE    
#> 3 2018-12-05 00:00:00     8 c     TRUE

或更简单地说,在NA中找到非filter

df %>%
  group_by(date_time) %>%
  filter(all(!is.na(value)))
#> # A tibble: 3 x 3
#> # Groups:   date_time [1]
#>   date_time           value class
#>   <dttm>              <dbl> <fct>
#> 1 2018-12-05 00:00:00     5 a    
#> 2 2018-12-05 00:00:00     5 b    
#> 3 2018-12-05 00:00:00     8 c

reprex package(v0.2.1)于2018-12-01创建