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)
您可以使用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 的解决方案将更适合,因为对于此方法,您必须手动指定列。不过,它确实有简短而甜蜜的好处。