在 R 数据框中按行查找最大绝对值
Find the maximum absolute value by row in an R data frame
我希望找到一种矢量化方法来从数据框中的多个列中获取绝对最大值。
基本上有一个等效于 pmax 函数的函数来获取绝对最大值。
test_df <- tibble(
some_identifier = c("apple", "tunafish", "turkey_sandwich"),
val_a = c(-1, 2, 0),
val_b = c(-3, 3, NA),
val_c = c(2, 3, 1)
)
# this is what abs_max column should be
test_df$abs_max <- c(-3, 3, 1)
test_df
# A tibble: 3 x 5
some_identifier val_a val_b val_c abs_max
<chr> <dbl> <dbl> <dbl> <dbl>
1 apple -1 -3 2 -3
2 tunafish 2 3 3 3
3 turkey_sandwich 0 NA 1 1
abs_max栏是我要创建的。一个不太理想的解决方案可能是遍历每一行;但想联系以确定可能的更好方法。
这是使用 max.col
的方法 - 感谢@Gregor
f <- 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)))]
}
f(test_df)
# [1] -3 3 1
循序渐进
我们所做的是在第一步中过滤数字列
Filter(is.numeric, test_df)
# val_a val_b val_c
#1 -1 -3 2
#2 2 3 3
#3 0 NA 1
(在上面的函数中调用了tmp
)
然后
replace(x <- abs(Filter(is.numeric, test_df)), is.na(x), -Inf))
returns
# val_a val_b val_c
#1 1 3 2
#2 2 3 3
#3 0 -Inf 1
这是一个 data.frame,其中 NA
被替换为 -Inf
,所有负值都被替换为它们的绝对值。
max.col
returns每行最大值的列位置
max.col(replace(x <- abs(Filter(is.numeric, test_df)), is.na(x), -Inf))
# [1] 2 2 3
此信息最终用于使用数字矩阵从 Filter(is.numeric, test_df)
中提取所需的值,即
cbind(1:nrow(Filter(is.numeric, test_df)),
max.col(replace(x <- abs(Filter(is.numeric, test_df)), is.na(x), -Inf)))
# [,1] [,2]
#[1,] 1 2
#[2,] 2 2
#[3,] 3 3
数据
test_df <- data.frame(
some_identifier = c("apple", "tunafish", "turkey_sandwich"),
val_a = c(-1, 2, 0),
val_b = c(-3, 3, NA),
val_c = c(2, 3, 1), stringsAsFactors = FALSE)
我希望找到一种矢量化方法来从数据框中的多个列中获取绝对最大值。
基本上有一个等效于 pmax 函数的函数来获取绝对最大值。
test_df <- tibble(
some_identifier = c("apple", "tunafish", "turkey_sandwich"),
val_a = c(-1, 2, 0),
val_b = c(-3, 3, NA),
val_c = c(2, 3, 1)
)
# this is what abs_max column should be
test_df$abs_max <- c(-3, 3, 1)
test_df
# A tibble: 3 x 5
some_identifier val_a val_b val_c abs_max
<chr> <dbl> <dbl> <dbl> <dbl>
1 apple -1 -3 2 -3
2 tunafish 2 3 3 3
3 turkey_sandwich 0 NA 1 1
abs_max栏是我要创建的。一个不太理想的解决方案可能是遍历每一行;但想联系以确定可能的更好方法。
这是使用 max.col
的方法 - 感谢@Gregor
f <- 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)))]
}
f(test_df)
# [1] -3 3 1
循序渐进
我们所做的是在第一步中过滤数字列
Filter(is.numeric, test_df)
# val_a val_b val_c
#1 -1 -3 2
#2 2 3 3
#3 0 NA 1
(在上面的函数中调用了tmp
)
然后
replace(x <- abs(Filter(is.numeric, test_df)), is.na(x), -Inf))
returns
# val_a val_b val_c
#1 1 3 2
#2 2 3 3
#3 0 -Inf 1
这是一个 data.frame,其中 NA
被替换为 -Inf
,所有负值都被替换为它们的绝对值。
max.col
returns每行最大值的列位置
max.col(replace(x <- abs(Filter(is.numeric, test_df)), is.na(x), -Inf))
# [1] 2 2 3
此信息最终用于使用数字矩阵从 Filter(is.numeric, test_df)
中提取所需的值,即
cbind(1:nrow(Filter(is.numeric, test_df)),
max.col(replace(x <- abs(Filter(is.numeric, test_df)), is.na(x), -Inf)))
# [,1] [,2]
#[1,] 1 2
#[2,] 2 2
#[3,] 3 3
数据
test_df <- data.frame(
some_identifier = c("apple", "tunafish", "turkey_sandwich"),
val_a = c(-1, 2, 0),
val_b = c(-3, 3, NA),
val_c = c(2, 3, 1), stringsAsFactors = FALSE)