Return the column name for the last value <> NA in row

Viewed 44

I have a data frame containing condition assessments with a rating from 1-7 (as the column names). Each observation contains a representative area (as a percentage) for each condition rating (1-7). Each row should sum to 100% for each observation.

I am able to return the corresponding condition rating (1-7 from the column name) for the highest % coverage to show the majority of the area is condition x.

Here's my code to do this:

# Create some data:
    set.seed(10)
    df <- matrix(round(rbeta(100*7,1,1),digits=1), nc=7)
    df <- round(sweep(df, 1, rowSums(df), FUN="/"),digits=1)
    colnames(df)<-c(1:7) # Change the column names to reflect condition value
    df <- as.data.frame(df)

# Now return the condition corresponding to the highest % coverage 
    df$maxPercCond <- as.numeric(colnames(df)[max.col(df,ties.method="last")])
    df[df == 0] <- NA # Need to keep this as actual data contains NA values

My Question

I need to return the peak condition (pkVal) for each row.

    df[c(5,70),]

     1   2   3   4   5   6   7      maxPercCond pkVal  | pkVal(REQUIRED)
  5  0.1 0.2 0.2 0.1 0.2 0.1  NA    5           0.1    | 6
  70 0.2 0.2 0.1 0.2 0.1 NA   0.1   4           0.1    | 7

In the above example, pkVal should equal 6 and 7 respectively (as per my manual pkVal(REQUIRED) entry to show that 6 was the highest rated condition for the first row and 7 was the highest rated condition for the second row.

I've been trying a variation on the maxPerCond assignment but getting tied up in knots! Any suggestions/assistance would be most welcome:

 df$pkVal <- as.numeric(colnames(df)[max.col(df[cbind( 1:nrow(df),
 max.col(!is.na(df[,1:7]),"last") )],ties.method="last")])
1 Answers

One option might be to use apply in row mode and find the column name of the corresponding last element which is not equal to NA:

apply(df, 1, function(x) { tail(names(x)[!is.na(x)], n=1) })
Related