Home > Enterprise >  Find last row per each column of a dataframe
Find last row per each column of a dataframe

Time:03-19

I have the following dataframe and I want to get a vector that contains the last non-NA row of each column:

df <- data.frame(a = 1:5, b = 6:10, c = c(rep(NA, 5)))
df <- rbind(df, rep(NA, ncol(df)), rep(NA, ncol(df)))
df[2,] <- NA
df$b[6]<-8

df
   a  b  c
1  1  6 NA
2 NA NA NA
3  3  8 NA
4  4  9 NA
5  5 10 NA
6 NA  8 NA
7 NA NA NA

The vector I am looking for would be as follows:

c(5,6,0)

How can I achieve this using base R? So far, I run the following formula...

apply(row(df)   0 * df, 2, function(x) max(x, na.rm = TRUE))

...but it throws me the following warning message:

Warning message: In max(x, na.rm = TRUE) : no non-missing arguments to max; returning -Inf

CodePudding user response:

sapply(df, function(z) c(rev(which(!is.na(z))), 0)[1])
# a b c 
# 5 6 0 

CodePudding user response:

Another incantation via Position, looking from the right=/end, for a non-NA (Negate(is.na)) value, returning a 0L if nomatch found.

sapply(df, Position, f=Negate(is.na), right=TRUE, nomatch=0L)
#a b c 
#5 6 0 

CodePudding user response:

You can use match like so:

f <- function(x) {
    if (n <- length(x)) n   1L - match(FALSE, is.na(x)[n:1L], n   1L) else 0L
}

sapply(df, f)
## a b c 
## 5 6 0

CodePudding user response:

An option with colMaxs

library(matrixStats)
colMaxs(row(df) * !is.na(df))
[1] 5 6 0
  • Related