如何获取最后一个非NA列的值

时间:2020-07-08 00:34:28

标签: r data-manipulation mutate

有点难以解释,但是我有一个数据框,其值看起来像一个阶梯-对于每个日期,有不同的列在某些日期具有NA。我想创建一个具有最后一个非NA列值的新列。

希望这个例子更有意义:

示例数据框:

test <- data.frame("date" = c(as.Date("2020-01-01"), as.Date("2020-01-02"), as.Date("2020-01-03")),
                   "a" = c(4, 3, 4),
                   "b" = c(NA, 2, 1),
                   "c" = c(NA, NA, 5))

所需的输出:

date............val
2020-01-01...... 4
2020-01-02...... 2
2020-01-03...... 5

我也不想做类似获取日期的行号和该列号+ 1的事情,但是如果那是唯一的方法,那就那样。谢谢!

3 个答案:

答案 0 :(得分:3)

这是一种基于Tidyverse的方法-使用pivot_longer将列转换为行,然后获取最后一个值不是每个日期的NA的行:

library(dplyr)
library(tidyr)

test %>% 
    pivot_longer(-date) %>% 
    filter(!is.na(value)) %>% 
    group_by(date) %>% 
    summarize(value = tail(value, 1), .groups = "drop")

答案 1 :(得分:2)

您可以将max.col设置为ties.method的情况下使用"last",以获取每行中的最后一个非NA值。

test$val <- test[cbind(1:nrow(test), max.col(!is.na(test), ties.method = 'last'))]
test

#        date a  b  c val
#1 2020-01-01 4 NA NA   4
#2 2020-01-02 3  2 NA   2
#3 2020-01-03 4  1  5   5

答案 2 :(得分:0)

您还可以使用dplyr的coalesce函数执行此操作,该函数从提供的向量中获取第一个非缺失元素。

library(dplyr)

test %>%
  mutate(val = coalesce(c, b, a))
#>         date a  b  c val
#> 1 2020-01-01 4 NA NA   4
#> 2 2020-01-02 3  2 NA   2
#> 3 2020-01-03 4  1  5   5

reprex package(v0.3.0)于2020-07-07创建

请注意,如果您有许多列,则@tfehring和@Ronak的解决方案将更适合,因为使用这种方法,您将必须手动指定列。不过,它的确具有短而甜的优点。