An option is max.col
from base R
to get the column index for each row where there is a non-NA element. The ties.method
can be "random"
, "first"
or "last"
. As we want the last
non-NA, specify the "last"
as ties.method
df$m <- names(df)[-1][max.col(!is.na(df[-1]), 'last')]
df$m
#[1] "m_3" "m_1" "m_2" "m_3"
Or for the second option, cbind
with row index and extract the elements
df[-1][cbind(seq_len(nrow(df)), max.col(!is.na(df[-1]), 'last'))]
#[1] "i" "b" "g" "l"
Or this can be done with tidyverse
library(dplyr)
df %>%
rowwise %>%
mutate(m = {tmp <- c_across(starts_with('m'))
tail(na.omit(tmp), 1)}) %>%
ungroup
Or if we want to get both at once, then an option is to reshape to 'long' format
library(tidyr)
df %>%
pivot_longer(cols = starts_with('m'), values_drop_na = TRUE,
names_to = "m_name", values_to = 'm_value') %>%
group_by(id) %>%
slice_tail(n = 1)%>%
ungroup %>%
right_join(df) %>%
select(names(df), everything())
-output
# A tibble: 4 x 6
# id m_1 m_2 m_3 m_name m_value
# <dbl> <chr> <chr> <chr> <chr> <chr>
#1 1 a e i m_3 i
#2 2 b <NA> <NA> m_1 b
#3 3 c g <NA> m_2 g
#4 4 d h l m_3 l
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…