dplyr::first()选择第一个非NA值

30

我正在寻找一种方法来从每个组中提取第一个和最后一个非NA值。我使用dplyr::first()和dplyr::last(),但我无法确定如何选择第一个或最后一个非NA值。

library(dplyr)
set.seed(123)
d <- data.frame(
  group = rep(1:3, each = 3),
  year = rep(seq(2000,2002,1),3),
  value = sample(1:9, r = T))

#Introduce NA values in first row of group 2 and last row of group 3
d %>%
  mutate(
    value = case_when(
      group == 2 & year ==2000 ~ NA_integer_,
      group == 3 & year ==2002 ~ NA_integer_,
      TRUE ~ value))%>%
  group_by(group) %>% 
  mutate(
    first = dplyr::first(value),
    last = dplyr::last(value))

结果(存在问题)

# A tibble: 9 x 5
# Groups:   group [3]
  group  year value first  last
  <int> <dbl> <int> <int> <int>
1     1  2000     3     3     4
2     1  2001     8     3     4
3     1  2002     4     3     4
4     2  2000    NA    NA     1
5     2  2001     9    NA     1
6     2  2002     1    NA     1
7     3  2000     5     5    NA
8     3  2001     9     5    NA
9     3  2002    NA     5    NA

你能帮我把第2组的“第一”列值设为9,并将第3组的“最后”一列值设为9吗?

如果存在tidyverse解决方案,则非常希望使用它。


1
删除NAs,请尝试:first(na.omit(value)) - zx8754
@zx8754 对于种子我很抱歉 - 我已经更正了。删除NA值是行不通的,因为这些行包含其他非NA值,而我需要这些值。 - Steen Harsted
我没有从数据框中删除NAs,而是只在first/last函数内部进行处理,请参见我下面编辑过的答案。 - zx8754
1个回答

45

使用na.omit,进行比较:

first(c(NA, 11, 22))
# [1] NA

first(na.omit(c(NA, 11, 22)))
# [1] 11

使用示例数据:

d %>%
  mutate(
    value = case_when(
      group == 2 & year ==2000 ~ NA_integer_,
      group == 3 & year ==2002 ~ NA_integer_,
      TRUE ~ value))%>%
  group_by(group) %>% 
  mutate(
    first = dplyr::first(na.omit(value)),
    last = dplyr::last(na.omit(value)))

# # A tibble: 9 x 5
# # Groups:   group [3]
#   group  year value first  last
#   <int> <dbl> <int> <int> <int>
# 1     1  2000     3     3     4
# 2     1  2001     8     3     4
# 3     1  2002     4     3     4
# 4     2  2000    NA     9     1
# 5     2  2001     9     9     1
# 6     2  2002     1     9     1
# 7     3  2000     5     5     9
# 8     3  2001     9     5     9
# 9     3  2002    NA     5     9

2
如果列全部为NA,或者在使用group_by时组内全部为NA,则此操作将失败。Summarise将只返回一个空的data.frame/tibble(无论是整体还是给定的组)。 - D Bolta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接