How to Find Maximum Absolute Values by Row in Data Frame in R
This article will explain how to find maximum absolute values by row in a data frame in R.
Use Custom Function to Find Maximum Absolute Values by Row in R Data Frame
Finding maximum absolute values in each row of the data frame and constructing them as a vector can be done using the abs_max
function that we implemented in the following code snippet. We assume the data frame contains numeric and non-numeric values and initialize an object called df1
for verification purposes. The first function called in the abs_max
block is Filter
. It takes two arguments. The first represents the unary function applied to each element of the vector passed as the second argument, and Filter
extracts the elements that evaluate true
. In this case, Filter
takes the is.numeric
function to extract only numeric values from the data frame.
Then, the inherits
function is utilized to check if the argument of the abs_max
is of type tbl_df
, and if so, it is converted to a matrix. Note that, tbl_df
class is commonly known as tibble
and is provided with the same name by a separate package, which we will utilize in the next example. The replace
function is called to replace negative values with their absolute value and the NA
types with -Inf
. The next, max.col
is invoked and extracts the vector of positions for the maximum values in each row. Finally, the result values are taken using the cbind
function. The latter object we can append to the existing data frame as a separate column named abs_max
as demonstrated in the following code sample.
abs_max <- function(data) {
tmp <- Filter(is.numeric, data)
if(inherits(data, "tbl_df")) {
tmp <- as.matrix(tmp)
}
tmp[cbind(1:nrow(tmp), max.col(replace(x <- abs(tmp), is.na(x), -Inf)))]
}
df1 <- data.frame(
id = c("foo", "bar", "goo"),
val_a = c(-51, 15, 19),
val_b = c(NA, 122, 35),
val_c = c(10, -23, 4)
)
df1$abs_max = abs_max(df1)
df1
Output:
id val_a val_b val_c abs_max
1 foo -51 NA 10 -51
2 bar 15 122 -23 122
3 goo 19 35 4 35
Alternatively, the same function can be used to pass the tibble
object type and process its rows. Note that tibbles will be converted to matrices in the abs_max
function, but the rest of the function code works the same way it did on the data frame.
library(tibble)
abs_max <- function(data) {
tmp <- Filter(is.numeric, data)
if(inherits(data, "tbl_df")) {
tmp <- as.matrix(tmp)
}
tmp[cbind(1:nrow(tmp), max.col(replace(x <- abs(tmp), is.na(x), -Inf)))]
}
tb1 <- tibble(
id = c("foo", "bar", "goo"),
val_a = c(-51, 15, 19),
val_b = c(NA, 122, 35),
val_c = c(10, -23, 4)
)
tb1$abs_max = abs_max(tb1)
tb1
Output:
# A tibble: 3 x 5
id val_a val_b val_c abs_max
<chr> <dbl> <dbl> <dbl> <dbl>
1 foo -51 NA 10 -51
2 bar 15 122 -23 122
3 goo 19 35 4 35
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook