行最小值,某些列除外

  • 本文关键字:最小值 r
  • 更新时间 :
  • 英文 :


我在下面有一个数据框。我需要找到行最小值和最大值,除了少数几列是字符。

df
x y z
1 1 1 a
2 2 5 b
3 7 4 c 

我需要

df
x y z  Min  Max
1 1 1 a   1    1
2 2 5 b   2    5   
3 7 4 c   4    7

另一种dplyr可能性可能是:

df %>%
mutate(Max = do.call(pmax, select_if(., is.numeric)),
Min = do.call(pmin, select_if(., is.numeric)))
x y z Max Min
1 1 1 a   1   1
2 2 5 b   5   2
3 7 4 c   7   4

或者提议的变体是@G. Grothendieck:

df %>% 
mutate(Min = pmin(!!!select_if(., is.numeric)), 
Max = pmax(!!!select_if(., is.numeric)))

另一个基本的R解决方案。仅对带有数字的列进行子集化,然后在每行中使用apply来获取带有range的最小值和最大值。

cbind(df, t(apply(df[sapply(df, is.numeric)], 1, function(x)
setNames(range(x, na.rm = TRUE), c("min", "max")))))
#  x y z min max
#1 1 1 a   1   1
#2 2 5 b   2   5
#3 7 4 c   4   7

1(这个单行不使用软件包:

transform(df, min = pmin(x, y), max = pmax(x, y))

给:

x y z min max
1 1 1 a   1   1
2 2 5 b   2   5
3 7 4 c   4   7

2(如果您有很多列并且不想将它们全部列出或确定自己哪些是数字,那么这也不使用包。

ix <- sapply(df, is.numeric)
transform(df, min = apply(df[ix], 1, min), max = apply(df[ix], 1, max))

如果您的实际数据具有 NA,并且如果您想在取最小值或最大值时忽略它们,则最小值、最大值、pmin 和 pmax 都采用可选的na.rm = TRUE参数。

注意

Lines <- "x y z
1 1 1 a
2 2 5 b
3 7 4 c"
df <- read.table(text = Lines)

1(我们可以使用select_if. 在这里,我们可以使用select_if来选择数字列,然后使用pminpmax获取行minmax并将其与原始数据集绑定

library(dplyr)
library(purrr)
df %>%
select_if(is.numeric) %>%
transmute(Min = reduce(., pmin, na.rm = TRUE),
Max = reduce(., pmax, na.rm = TRUE)) %>%
bind_cols(df, .) 
#  x y z Min Max
#1 1 1 a   1   1
#2 2 5 b   2   5
#3 7 4 c   4   7

注意:在这里,我们只使用select_if的单一表达式


2( 同样可以在base R中完成(不使用软件包(

i1 <- names(which(sapply(df, is.numeric)))
df['Min'] <- do.call(pmin, c(df[i1], na.rm = TRUE))
df['Max'] <- do.call(pmax, c(df[i1], na.rm = TRUE))

此外,如评论中所述,这是通用选项。 如果只针对两列,则只需执行pmin(x, y)pmax(x,y)操作是可能的,并且不会检查列是否numeric,并且这不是通用解决方案

注意:此处提到的所有解决方案要么首先回答,要么来自OP的评论

数据

df <- structure(list(x = c(1L, 2L, 7L), y = c(1L, 5L, 4L), z = c("a", 
"b", "c")), class = "data.frame", row.names = c("1", "2", "3"
))

最新更新