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

Kat*_*thy 3 r data-manipulation dplyr

解释起来有点困难,但我有一个数据框,其值看起来像楼梯 - 对于每个日期,都有不同的列,某些日期的值不适用。我想创建一个新列,其中包含最后一个非 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))
Run Code Online (Sandbox Code Playgroud)

期望的输出:

date............val
2020-01-01...... 4
2020-01-02...... 2
2020-01-03...... 5
Run Code Online (Sandbox Code Playgroud)

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

小智 7

这是一种基于 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")
Run Code Online (Sandbox Code Playgroud)


Ron*_*hah 5

您可以使用max.colset ties.methodas"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
Run Code Online (Sandbox Code Playgroud)


小智 5

您还可以使用 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
Run Code Online (Sandbox Code Playgroud)

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

请注意,如果您有很多列,@tfehring 和 @Ronak 的解决方案将更适合,因为对于此方法,您必须手动指定列。不过,它确实有简短而甜蜜的好处。