【问题标题】:Using dplyr first and last but ignoring NA values首先和最后使用 dplyr 但忽略 NA 值
【发布时间】:2016-07-06 17:38:08
【问题描述】:

我有以下数据框,我需要忽略 id 9 的最后一个值的缺失值。

firstlast <- data.frame(id = as.factor(c("01", "01", "01", "01", "01", "04", "04", "05", "05", "05", "05", "05", "09", "09", "09", "09", "09")),
                 var_a = c(13, 21, 32, 33, 44, 21, 33, 35, 17, 18, 21, 22, 17, 13, 33, 32, NA))

df 看起来像:

   id var_a
1  01    13
2  01    21
3  01    32
4  01    33
5  01    44
6  04    21
7  04    33
8  05    35
9  05    17
10 05    18
11 05    21
12 05    22
13 09    17
14 09    13
15 09    33
16 09    32
17 09    NA

到目前为止我的尝试:

firstlast <- firstlast %>% group_by(id) %>%
  mutate(var_first = first(var_a)) %>%
  mutate(var_last = last(var_a)) %>%
  mutate(change = var_last - var_first)

创建:

       id var_a var_first var_last change
   (fctr) (dbl)     (dbl)    (dbl)  (dbl)
1      01    13        13       44     31
2      01    21        13       44     31
3      01    32        13       44     31
4      01    33        13       44     31
5      01    44        13       44     31
6      04    21        21       33     12
7      04    33        21       33     12
8      05    35        35       22    -13
9      05    17        35       22    -13
10     05    18        35       22    -13
11     05    21        35       22    -13
12     05    22        35       22    -13
13     09    17        17       NA     NA
14     09    13        17       NA     NA
15     09    33        17       NA     NA
16     09    32        17       NA     NA
17     09    NA        17       NA     NA

但是,我需要忽略 id 9 的最后一个 NA 观察值的缺失值,而是使用倒数第二个(或第一个观察到的值)。当我在该行包含mutate(var_last = last(var_a), na.rm=TRUE) 时,我会得到一整列 na.rm = TRUE 并且不会忽略 NA 值。

我希望达到的最终df是......

       id var_a var_first var_last change
   (fctr) (dbl)     (dbl)    (dbl)  (dbl)
1      01    13        13       44     31
2      01    21        13       44     31
3      01    32        13       44     31
4      01    33        13       44     31
5      01    44        13       44     31
6      04    21        21       33     12
7      04    33        21       33     12
8      05    35        35       22    -13
9      05    17        35       22    -13
10     05    18        35       22    -13
11     05    21        35       22    -13
12     05    22        35       22    -13
13     09    17        17       32     15
14     09    13        17       32     15
15     09    33        17       32     15
16     09    32        17       32     15
17     09    NA        17       32     15

谢谢!

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    mutate 没有na.rm 选项,first()last() 也没有,这在这里更合适。您可以使用na.omit 自己省略缺失值:

    firstlast <- firstlast %>% group_by(id) %>%
        mutate(
            var_first = first(na.omit(var_a)),
            var_last = last(na.omit(var_a)),
            change = var_last - var_first
        )
    # Source: local data frame [17 x 5]
    # Groups: id [4]
    # 
    #        id var_a var_first var_last change
    #    (fctr) (dbl)     (dbl)    (dbl)  (dbl)
    # 1      01    13        13       44     31
    # 2      01    21        13       44     31
    # 3      01    32        13       44     31
    # 4      01    33        13       44     31
    # 5      01    44        13       44     31
    # 6      04    21        21       33     12
    # 7      04    33        21       33     12
    # 8      05    35        35       22    -13
    # 9      05    17        35       22    -13
    # 10     05    18        35       22    -13
    # 11     05    21        35       22    -13
    # 12     05    22        35       22    -13
    # 13     09    17        17       32     15
    # 14     09    13        17       32     15
    # 15     09    33        17       32     15
    # 16     09    32        17       32     15
    # 17     09    NA        17       32     15
    

    作为旁注,给mutate 一个na.rm 参数没有多大意义。你会省略哪些NA 值?计算中使用的任何列中的任何行?其他输入?只是结果?您将如何填充已删除的行以仍然具有相同的值?最好像上面那样明确。

    【讨论】:

    • 我不知道为什么,但是Error: Unsupported vector type language 对我来说是错误的。也许是一个错误......无论如何,一个稍微不那么漂亮的解决方法:mutate(var_first = na.omit(var_a)[[1]], var_last = rev(na.omit(var_a))[[1]])
    • 嗯,你加载的是什么版本的dplyr?我的 0.4.3 已经过时了,但我希望它可以与任何更新的东西一起使用。尽管na.omit 确实添加了一个可能会妨碍您的属性。
    • 另一种选择是将na.omit(var_a) 替换为var_a[!is.na(var_a)] 就像akrun 的回答一样,这可能比na.omit(var_a)[[1]] 更透明
    • 我正在使用 0.5.0 版本来实现新功能。我应该看看新闻;可能有一些关于属性处理的事情。
    • 谢谢@Gregor,因为这确实有道理。干杯。
    【解决方案2】:

    这是一个使用data.table的选项

     library(data.table)
     setDT(firstlast)[,  c("var_first", "var_last") := .(var_a[!is.na(var_a)][1], 
           tail(var_a[!is.na(var_a)], 1)), 
                    , by = id][, change := var_last - var_first][]
    #     id var_a var_first var_last change
    # 1: 01    13        13       44     31
    # 2: 01    21        13       44     31
    # 3: 01    32        13       44     31
    # 4: 01    33        13       44     31
    # 5: 01    44        13       44     31
    # 6: 04    21        21       33     12
    # 7: 04    33        21       33     12
    # 8: 05    35        35       22    -13
    # 9: 05    17        35       22    -13
    #10: 05    18        35       22    -13
    #11: 05    21        35       22    -13
    #12: 05    22        35       22    -13
    #13: 09    17        17       32     15
    #14: 09    13        17       32     15
    #15: 09    33        17       32     15
    #16: 09    32        17       32     15
    #17: 09    NA        17       32     15
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-02
      • 2016-02-21
      • 1970-01-01
      • 2019-01-22
      • 1970-01-01
      • 1970-01-01
      • 2021-08-12
      • 2020-08-11
      相关资源
      最近更新 更多