按行选择第一个非 NA 值

问题描述

我有这样的数据:

df <- data.frame(id=c(1,2,3,4),A=c(6,NA,B=c(3,NA),C=c(4,5,D=c(4,1,2))

   id A  B  C D
1  1  6  3  4 4
2  2 NA  2  3 3
3  3 NA NA  5 1
4  4  4 NA NA 2

对于每一行:如果该行在“A”列中具有非NA 值,我希望将该值输入到新列“E”中。如果没有,我想转到“B”列,然后将该值输入到 E 中。依此类推。因此,新列将是 E = c(6,4)

我想使用 ifelse 函数,但我不太确定如何执行此操作。

解决方法

tidyverse

library(dplyr)
mutate(df,E = coalesce(A,B,C,D))
#   id  A  B  C D E
# 1  1  6  3  4 4 6
# 2  2 NA  2  3 3 2
# 3  3 NA NA  5 1 5
# 4  4  4 NA NA 2 4

coalesce 实际上是“返回每个向量中的第一个非NA。它有一个 SQL 等价物(或者实际上是 SQL 的 COALESCE 等价物)。

基础 R

df$E <- apply(df[,-1],1,function(z) na.omit(z)[1])
df
#   id  A  B  C D E
# 1  1  6  3  4 4 6
# 2  2 NA  2  3 3 2
# 3  3 NA NA  5 1 5
# 4  4  4 NA NA 2 4

na.omit 删除所有 NA 值,而 [1] 确保我们总是只返回第一个[1] 相对于(比如说)head(.,1) 的优势在于,如果没有非head 元素,NULL 将返回 NA,而 .[1]将始终至少返回一个 NA(向您表明这是唯一的选择)。