【问题标题】:Filter a dataset only to after first NA in column in R仅将数据集过滤到 R 中列中的第一个 NA 之后
【发布时间】:2021-03-10 14:56:37
【问题描述】:

我有一个数据集,我试图根据日期的顺序仅筛选出第一次非 NA 观察后的数据。

mock.data <- data.frame( id = c(1, 1, 1, 1, 1,  
                            2, 2, 2, 2, 2,
                            3, 3, 3, 3, 3 ),
                     date = as.Date(c("1934-06-03", "1938-06-17",  "1943-06-23", "1948-06-17", "1953-06-23",
                              "1911-09-24", "1914-04-07", "1917-09-16", "1920-09-17", "1924-09-17",
                              "2008-09-09", "2012-10-06", "2016-10-14", "2020-03-03", "2022-04-14")),
                     price = c(33, 54, NA, 55, 67,
                               NA, NA, 19, NA, 22,
                               NA, 98, 87, 102, NA))

mock.data



 id       date price
  1 1934-06-03    33
  1 1938-06-17    54
  1 1943-06-23    NA
  1 1948-06-17    55
  1 1953-06-23    67
  2 1911-09-24    NA
  2 1914-04-07    NA
  2 1917-09-16    19
  2 1920-09-17    NA
  2 1924-09-17    22
  3 2008-09-09    NA
  3 2012-10-06    98
  3 2016-10-14    87
  3 2020-03-03   102
  3 2022-04-14    NA

我想要基本上将其过滤到每个price 中的第一个NA 之后的那些值id,但保留NA 在第一个非NA 之后出现的值。因此,理想情况下,我将获得以下信息:

ideal.data <- data.frame( id = c(1, 1, 1, 1, 1, 
                              2, 2, 2,
                             3, 3, 3,3 ),
                      date = as.Date(c("1934-06-03", "1938-06-17",  "1943-06-23", "1948-06-17", "1953-06-23",
                                       "1917-09-16", "1920-09-17", "1924-09-17",
                                       "2012-10-06", "2016-10-14", "2020-03-03", "2022-04-14")),
                      price = c(33, 54, NA, 55, 67,
                                19,NA, 22,
                                98, 87, 102, NA))

我尝试了多种方法,主要基于 tidy,如下所示:

library(tidyverse)


mock.data%>%
group_by(id)%>%
  arrange(date)%>%
  filter( date > date[min(is.na(price))])

但是我遇到了很多错误,无法完全得到我要查找的内容。非常欢迎任何帮助!

【问题讨论】:

    标签: r dplyr tidyverse tidyr


    【解决方案1】:

    使用ave 的基本 R 选项

    subset(
      mock.data,
      ave(!is.na(price), id, FUN = function(v) seq_along(v) >= which(v)[1])
    )
    

    给予

       id       date price
    1   1 1934-06-03    33
    2   1 1938-06-17    54
    3   1 1943-06-23    NA
    4   1 1948-06-17    55
    5   1 1953-06-23    67
    8   2 1917-09-16    19
    9   2 1920-09-17    NA
    10  2 1924-09-17    22
    12  3 2012-10-06    98
    13  3 2016-10-14    87
    14  3 2020-03-03   102
    15  3 2022-04-14    NA
    

    【讨论】:

    • 对不起,我意识到我的ideal.data中有错误,现在已更正
    【解决方案2】:

    我们可以使用cummax

    library(dplyr)
    mock.data %>%
       group_by(id) %>%
       filter(cummax(!is.na(price)) > 0) %>%
       ungroup
    

    -输出

    # A tibble: 12 x 3
    #      id date       price
    #   <dbl> <date>     <dbl>
    # 1     1 1934-06-03    33
    # 2     1 1938-06-17    54
    # 3     1 1943-06-23    NA
    # 4     1 1948-06-17    55
    # 5     1 1953-06-23    67
    # 6     2 1917-09-16    19
    # 7     2 1920-09-17    NA
    # 8     2 1924-09-17    22
    # 9     3 2012-10-06    98
    #10     3 2016-10-14    87
    #11     3 2020-03-03   102
    #12     3 2022-04-14    NA
    

    【讨论】:

    • 出色的cummax 方法!
    猜你喜欢
    • 1970-01-01
    • 2014-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-05
    • 1970-01-01
    相关资源
    最近更新 更多