使用dplyr first和last,但忽略NA值

使用dplyr first和last,但忽略NA值,r,dplyr,R,Dplyr,我有下面的数据帧,我需要忽略ID9最后一个值的缺失值 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,

我有下面的数据帧,我需要忽略ID9最后一个值的缺失值

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))
我迄今为止的努力:

firstlast <- firstlast %>% group_by(id) %>%
  mutate(var_first = first(var_a)) %>%
  mutate(var_last = last(var_a)) %>%
  mutate(change = var_last - var_first)
但是,我需要忽略id 9的最后一次NA观测缺少的值,而是使用倒数第二次(或第一次观测值)。当我在该行包含
mutate(var_last=last(var_a),na.rm=TRUE)
时,我会得到na.rm=TRUE的完整列,并且不会忽略na值

我希望达到的目的是

       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
选项,也没有在此处更合适的
first()
last()
选项。您可以使用
na忽略缺少的值。忽略

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
firstlast%groupby(id)%>%
变异(
var_first=first(na.省略(var_a)),
var_last=last(na.省略(var_a)),
change=var\u last-var\u first
)
#来源:本地数据帧[17 x 5]
#组别:id[4]
# 
#id变量a变量第一个变量最后一次更改
#(fctr)(dbl)(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
值?计算中使用的任何列中的任何行?其他投入?结果如何?如何填充删除的行,使其仍具有相同的值?最好像上面那样显式。

这里有一个使用
数据的选项。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

我不知道为什么,但这对我来说是错误的
错误:不支持的向量类型语言
。也许是一个bug……无论如何,一个稍微不太好的解决方法:
mutate(var_first=na.omit(var_a)[[1]],var_last=rev(na.omit(var_a))[[1]])
Hmm,你加载了什么版本的
dplyr
?我的0.4.3版本已经过时了,但我希望它能与任何更新的版本一起工作。虽然
na.ommit
确实添加了一个可能会妨碍的属性。另一个选择是将
na.ommit(var_a)
替换为
var_a[!is.na(var_a)]
就像akrun的回答一样,这可能比
na.ommit(var_a)[[1]
我正在使用0.5.0版来实现新函数。我应该查看新闻;可能有一些关于属性处理的问题。谢谢@Gregor,这很有意义。干杯
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
 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